3 ms·
An important part of futexes, which the article mentions only in passing, is that the kernel will also check a condition atomically with the wait operation; if
by bonzini 8y ago
An important part of futexes, which the article mentions only in passing, is that the kernel will also check a condition atomically with the wait operation; if the condition isn't satisfied the wait will not be performed. This avoids races between a thread that unlocks the mutex right after another thread has invoked the system call.
Effectively, inside the kernel the algorithm is
lock wait queue
if (*var == val)
add myself to wait queue
unlock wait queue
wait until queue wakes me up
else
unlock wait queue
- eliben 8y agoThanks for mentioning this, it's indeed one of the interesting subtleties of futex(). In my defense, I explicitly say in the post that it's not a replacement for the man page and suggest the readers at least go through the descriptions of FUTEX_WAIT and FUTEX_WAKE. The former explains this behavior in the very first sentence. Moreover, the post mentions this behavior twice: 1. When explaining spurious wakeups in the wait_on_futex_value [...] FUTEX_WAIT will immediately return if the value at the futex address is not equal to val. In our case this can happen if the child issued a wait before the parent wrote 0xA, for example. 2. In a comment inside Mutex::lock() // We're here when either: // (a) the mutex was in fact unlocked (by an intervening thread). But your point on avoiding an insidious deadlock is spot on.
- bonzini 8y agoIndeed it is mentioned. I wrote the comment because repeating the check in the kernel on a user provided value is what distinguishes futexes from a condvar. Of course muted+condvar+int is not a replacement if you're implementing pthreads, but it's also much less efficient than futexes if you're implementing a synchronization primitive not provided by pthreads. (The most common use of futexes that I have seen outside glibc is to implement binary semaphores. Binary semaphores can be a lighter-weight alternative to condition variables when only a single thread can ever wait on an event).
- cozzyd 8y agoIn my experience futexes are primarily used to confound valgrind. Damn you libgomp (yeah I know you can recompile gcc to use pthreads in the openmp implementation).