Hi,

It seems that some code paths in libdiskfs still leave a mutex locked
somewhere. The original WAIT_DEBUG code in libthreads records the
thread which is holding the lock, but this is not really usefull in
Hurd's translators, since that thread is probably waiting for another
message just as everyone else, thus hiding the path that forgot to
unlock the mutex.

This patch changes mutex_lock/mutex_unlock macros to hold a pointer to
the name of the function that holds the mutex. This way, is possible
to do this:

<snip>
(gdb) print disk_cache_lock
$1 = {held = 1, lock = 0, name = 0x0, queue = {head = 0x0, tail = 0x0}, 
  fname = 0x805c8de}
(gdb) x/s 0x805c8de
0x805c8de <__FUNCTION__.11276>:  "disk_pager_read_page"
</snip>

I've preferred to create a new definition conditional instead of using
WAIT_DEBUG, since this one changes cproc_t structure size.

Only in libthreads: .svn
Common subdirectories: libthreads.orig/alpha and libthreads/alpha
diff -du libthreads.orig/cthreads.h libthreads/cthreads.h
--- libthreads.orig/cthreads.h	2010-05-14 10:14:33.000000000 +0000
+++ libthreads/cthreads.h	2010-05-14 10:22:24.000000000 +0000
@@ -275,6 +275,12 @@
 #define	FALSE	0
 #endif
 
+/* 
+ * Enable mutex holder debugging 
+ */
+
+#define MUTEX_HOLDER_DEBUG
+
 /*
  * C Threads package initialization.
  */
@@ -382,8 +388,8 @@
 	spin_lock_t lock;
 	const char *name;
 	struct cthread_queue queue;
-	/* holder is for WAIT_DEBUG. Not ifdeffed to keep size constant. */
-	struct cthread *holder;
+	/* fname is for WAIT_DEBUG. Not ifdeffed to keep size constant. */
+	void *fname;
 } *mutex_t;
 
 /* Rearranged accordingly for GNU: */
@@ -396,7 +402,7 @@
 	spin_lock_init(&(m)->lock); \
 	cthread_queue_init(&(m)->queue); \
 	spin_lock_init(&(m)->held); \
-	(m)->holder = 0; \
+	(m)->fname = 0; \
 	MACRO_END
 #define	mutex_set_name(m, x)	((m)->name = (x))
 #define	mutex_name(m)		((m)->name != 0 ? (m)->name : "?")
@@ -404,13 +410,13 @@
 #define	mutex_free(m)		free((m))
 
 #define mutex_try_lock(m) spin_try_lock(&(m)->held)
-#if defined(WAIT_DEBUG)
+#if defined(MUTEX_HOLDER_DEBUG)
 #define mutex_lock(m) \
 	MACRO_BEGIN \
 	if (!spin_try_lock(&(m)->held)) { \
 		__mutex_lock_solid(m); \
 	} \
-	(m)->holder = cthread_self(); \
+	(m)->fname = &__FUNCTION__; \
 	MACRO_END
 #define mutex_unlock(m) \
 	MACRO_BEGIN \
@@ -418,9 +424,9 @@
 	    cthread_queue_head(&(m)->queue, vm_offset_t) != 0) { \
 		__mutex_unlock_solid(m); \
 	} \
-	(m)->holder = 0; \
+	(m)->fname = 0; \
 	MACRO_END
-#else /* defined(WAIT_DEBUG */
+#else /* defined(MUTEX_HOLDER_DEBUG) */
 #define mutex_lock(m) \
 	MACRO_BEGIN \
 	if (!spin_try_lock(&(m)->held)) { \
@@ -434,7 +440,7 @@
 		__mutex_unlock_solid(m); \
 	} \
 	MACRO_END
-#endif /* defined(WAIT_DEBUG) */
+#endif /* defined(MUTEX_HOLDER_DEBUG) */
 /*
  * Condition variables.
  */
Common subdirectories: libthreads.orig/i386 and libthreads/i386

Reply via email to