diff options
author | Jens Gustedt <Jens.Gustedt@inria.fr> | 2018-01-03 14:17:12 +0100 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2018-01-09 13:10:12 -0500 |
commit | 47d0bcd4762f223364e5b58d5a381aaa0cbd7c38 (patch) | |
tree | e73dfc04306ff6f03f1e2712aa3c14321866df8a /src/internal/pthread_impl.h | |
parent | b583c5d3b4cc2c54c68eef5eb7855ecfacee8bfc (diff) | |
download | musl-47d0bcd4762f223364e5b58d5a381aaa0cbd7c38.tar.gz musl-47d0bcd4762f223364e5b58d5a381aaa0cbd7c38.tar.xz musl-47d0bcd4762f223364e5b58d5a381aaa0cbd7c38.zip |
new lock algorithm with state and congestion count in one atomic int
A variant of this new lock algorithm has been presented at SAC'16, see https://hal.inria.fr/hal-01304108. A full version of that paper is available at https://hal.inria.fr/hal-01236734. The main motivation of this is to improve on the safety of the basic lock implementation in musl. This is achieved by squeezing a lock flag and a congestion count (= threads inside the critical section) into a single int. Thereby an unlock operation does exactly one memory transfer (a_fetch_add) and never touches the value again, but still detects if a waiter has to be woken up. This is a fix of a use-after-free bug in pthread_detach that had temporarily been patched. Therefore this patch also reverts c1e27367a9b26b9baac0f37a12349fc36567c8b6 This is also the only place where internal knowledge of the lock algorithm is used. The main price for the improved safety is a little bit larger code. Under high congestion, the scheduling behavior will be different compared to the previous algorithm. In that case, a successful put-to-sleep may appear out of order compared to the arrival in the critical section.
Diffstat (limited to 'src/internal/pthread_impl.h')
-rw-r--r-- | src/internal/pthread_impl.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 56e19348..602d6f56 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -136,6 +136,12 @@ static inline void __wake(volatile void *addr, int cnt, int priv) __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); } +static inline void __futexwait(volatile void *addr, int val, int priv) +{ + if (priv) priv = FUTEX_PRIVATE; + __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val) != -ENOSYS || + __syscall(SYS_futex, addr, FUTEX_WAIT, val); +} void __acquire_ptc(void); void __release_ptc(void); |