diff options
author | Rich Felker <dalias@aerifal.cx> | 2014-08-17 22:09:47 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2014-08-17 22:09:47 -0400 |
commit | 37195db8ec31300a87bc7ec09d2adcf299e9203d (patch) | |
tree | f3d2bbb1ced5199a695a03bfb4d42ba06b7bc8a7 /src/internal/pthread_impl.h | |
parent | 4220d298ef7a2226b14fe4b481f7f7699eab6e3f (diff) | |
download | musl-37195db8ec31300a87bc7ec09d2adcf299e9203d.tar.gz |
redesign cond var implementation to fix multiple issues
the immediate issue that was reported by Jens Gustedt and needed to be
fixed was corruption of the cv/mutex waiter states when switching to
using a new mutex with the cv after all waiters were unblocked but
before they finished returning from the wait function.
self-synchronized destruction was also handled poorly and may have had
race conditions. and the use of sequence numbers for waking waiters
admitted a theoretical missed-wakeup if the sequence number wrapped
through the full 32-bit space.
the new implementation is largely documented in the comments in the
source. the basic principle is to use linked lists initially attached
to the cv object, but detachable on signal/broadcast, made up of nodes
residing in automatic storage (stack) on the threads that are waiting.
this eliminates the need for waiters to access the cv object after
they are signaled, and allows us to limit wakeup to one waiter at a
time during broadcasts even when futex requeue cannot be used.
performance is also greatly improved, roughly double some tests.
basically nothing is changed in the process-shared cond var case,
where this implementation does not work, since processes do not have
access to one another's local storage.
Diffstat (limited to 'src/internal/pthread_impl.h')
-rw-r--r-- | src/internal/pthread_impl.h | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 848ff668..2d090f8f 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -66,14 +66,13 @@ struct __timer { #define _m_prev __u.__p[3] #define _m_next __u.__p[4] #define _m_count __u.__i[5] -#define _c_mutex __u.__p[0] +#define _c_shared __u.__p[0] #define _c_seq __u.__i[2] #define _c_waiters __u.__i[3] #define _c_clock __u.__i[4] -#define _c_lock __u.__i[5] -#define _c_lockwait __u.__i[6] -#define _c_waiters2 __u.__i[7] -#define _c_destroy __u.__i[8] +#define _c_lock __u.__i[8] +#define _c_head __u.__p[1] +#define _c_tail __u.__p[5] #define _rw_lock __u.__i[0] #define _rw_waiters __u.__i[1] #define _rw_shared __u.__i[2] |