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