[asterisk-commits] russell: branch russell/debug_threads r77862 - in /team/russell/debug_threads...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Aug 1 11:49:17 CDT 2007


Author: russell
Date: Wed Aug  1 11:49:16 2007
New Revision: 77862

URL: http://svn.digium.com/view/asterisk?view=rev&rev=77862
Log:
Track the lock that a thread is waiting on as well.  Before, it only listed
the locks successfully acquired.  This should now give a pretty clear picture of
most deadlocks.

Modified:
    team/russell/debug_threads/include/asterisk/lock.h
    team/russell/debug_threads/utils.c

Modified: team/russell/debug_threads/include/asterisk/lock.h
URL: http://svn.digium.com/view/asterisk/team/russell/debug_threads/include/asterisk/lock.h?view=diff&rev=77862&r1=77861&r2=77862
==============================================================================
--- team/russell/debug_threads/include/asterisk/lock.h (original)
+++ team/russell/debug_threads/include/asterisk/lock.h Wed Aug  1 11:49:16 2007
@@ -219,6 +219,8 @@
 void ast_store_lock_info(const char *filename, int line_num, 
 	const char *func, const char *lock_name, void *lock_addr);
 
+void ast_mark_lock_acquired(void);
+
 void ast_remove_lock_info(void *lock_addr);
 
 static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
@@ -226,6 +228,8 @@
 {
 	int res;
 	int canlog = strcmp(filename, "logger.c");
+
+	ast_store_lock_info(filename, lineno, func, mutex_name, &t->mutex);
 
 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE)
 	if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
@@ -261,7 +265,7 @@
 #endif /* DETECT_DEADLOCKS */
 
 	if (!res) {
-		ast_store_lock_info(filename, lineno, func, mutex_name, &t->mutex);
+		ast_mark_lock_acquired();
 		if (t->reentrancy < AST_MAX_REENTRANCY) {
 			t->file[t->reentrancy] = filename;
 			t->lineno[t->reentrancy] = lineno;
@@ -273,6 +277,7 @@
 							   filename, lineno, func, mutex_name);
 		}
 	} else {
+		ast_remove_lock_info(&t->mutex);
 		__ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
 				   filename, lineno, func, strerror(res));
 #ifdef THREAD_CRASH
@@ -300,8 +305,10 @@
 	}
 #endif /* defined(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE) */
 
+	ast_store_lock_info(filename, lineno, func, mutex_name, &t->mutex);
+
 	if (!(res = pthread_mutex_trylock(&t->mutex))) {
-		ast_store_lock_info(filename, lineno, func, mutex_name, &t->mutex);
+		ast_mark_lock_acquired();
 		if (t->reentrancy < AST_MAX_REENTRANCY) {
 			t->file[t->reentrancy] = filename;
 			t->lineno[t->reentrancy] = lineno;
@@ -312,6 +319,8 @@
 			__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
 							   filename, lineno, func, mutex_name);
 		}
+	} else {
+		ast_remove_lock_info(&t->mutex);
 	}
 
 	return res;

Modified: team/russell/debug_threads/utils.c
URL: http://svn.digium.com/view/asterisk/team/russell/debug_threads/utils.c?view=diff&rev=77862&r1=77861&r2=77862
==============================================================================
--- team/russell/debug_threads/utils.c (original)
+++ team/russell/debug_threads/utils.c Wed Aug  1 11:49:16 2007
@@ -520,6 +520,8 @@
 		const char *lock_name;
 		void *lock_addr;
 		int times_locked;
+		/*! This thread is waiting on this lock */
+		unsigned int pending:1;
 	} locks[AST_MAX_LOCKS];
 	/*! This is the number of locks currently held by this thread.
 	 *  The index (num_locks - 1) has the info on the last one in the
@@ -568,7 +570,8 @@
  *
  * This function gets called in ast_mutex_lock() and ast_mutex_trylock() so
  * that information about this lock can be stored in this thread's
- * lock info struct.
+ * lock info struct.  The lock is marked as pending as the thread is waiting
+ * on the lock.  ast_mark_lock_acquired() will mark it as held by this thread.
  */
 void ast_store_lock_info(const char *filename, int line_num, 
 	const char *func, const char *lock_name, void *lock_addr)
@@ -603,8 +606,25 @@
 	lock_info->locks[i].lock_name = lock_name;
 	lock_info->locks[i].lock_addr = lock_addr;
 	lock_info->locks[i].times_locked = 1;
+	lock_info->locks[i].pending = 1;
 	lock_info->num_locks++;
 
+	pthread_mutex_unlock(&lock_info->lock);
+}
+
+/*!
+ * \brief Mark the last lock as acquired
+ */
+void ast_mark_lock_acquired(void)
+{
+	struct thr_lock_info *lock_info;
+	int i;
+
+	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
+		return;
+
+	pthread_mutex_lock(&lock_info->lock);
+	lock_info->locks[lock_info->num_locks - 1].pending = 0;
 	pthread_mutex_unlock(&lock_info->lock);
 }
 
@@ -671,7 +691,8 @@
 			lock_info->thread_name);
 		pthread_mutex_lock(&lock_info->lock);
 		for (i = 0; i < lock_info->num_locks; i++) {
-			ast_cli(fd, "=== ---> Lock #%d: %s %d %s %s %p (%d)\n", i,
+			ast_cli(fd, "=== ---> %sLock #%d: %s %d %s %s %p (%d)\n", 
+				lock_info->locks[i].pending ? "Waiting for " : "", i,
 				lock_info->locks[i].file, lock_info->locks[i].line_num,
 				lock_info->locks[i].func, lock_info->locks[i].lock_name,
 				lock_info->locks[i].lock_addr, 




More information about the asterisk-commits mailing list