Index: pthread_mutex.c =================================================================== RCS file: /cvsroot/src/lib/libpthread/pthread_mutex.c,v retrieving revision 1.56 diff -p -u -r1.56 pthread_mutex.c --- pthread_mutex.c 21 Mar 2013 16:49:12 -0000 1.56 +++ pthread_mutex.c 2 Feb 2014 19:58:49 -0000 @@ -311,9 +311,24 @@ pthread__mutex_lock_slow(pthread_mutex_t * sys/kern/kern_mutex.c for details. * In short, we must spin if we see * that the holder is running again. + * + * After we have observed the holder + * not running, we must issue a + * membar_consumer and reload + * ptm_owner so that if the holder + * wrote NULL to ptm_owner before it + * was preempted, we will observe the + * NULL write now and not some time + * later when we have decided to sleep + * with nobody around to wake us. + * Preemption issues membar_producer + * before it reports the thread not + * running, which matches this + * membar_consumer. */ - membar_sync(); - next = pthread__mutex_spin(ptm, owner); + (void)pthread__mutex_spin(ptm, owner); + membar_consumer(); + next = ptm->ptm_owner; } } Index: pthread_types.h =================================================================== RCS file: /cvsroot/src/lib/libpthread/pthread_types.h,v retrieving revision 1.13 diff -p -u -r1.13 pthread_types.h --- pthread_types.h 2 Aug 2008 19:46:30 -0000 1.13 +++ pthread_types.h 2 Feb 2014 19:58:49 -0000 @@ -109,7 +109,7 @@ struct __pthread_mutex_st { uint8_t ptm_pad2[3]; #endif volatile pthread_t ptm_owner; - pthread_t * volatile ptm_waiters; + volatile pthread_t ptm_waiters; unsigned int ptm_recursed; void *ptm_spare2; /* unused - backwards compat */ };