]> git.hungrycats.org Git - linux/commit
[PATCH] Add FUTEX_CMP_REQUEUE futex op
authorAndrew Morton <akpm@osdl.org>
Tue, 1 Jun 2004 01:48:47 +0000 (18:48 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 1 Jun 2004 01:48:47 +0000 (18:48 -0700)
commit9b91d73bde9d68800f9e5c338c0cf9d0fe3bc862
treed17e9b7c1681f00096d96ea5495f5df5822b49f7
parent673a68e627312d056cadd1e7053a9fc113149333
[PATCH] Add FUTEX_CMP_REQUEUE futex op

From: Jakub Jelinek <jakub@redhat.com>

FUTEX_REQUEUE operation has been added to the kernel mainly to improve
pthread_cond_broadcast which previously used FUTEX_WAKE INT_MAX op.
pthread_cond_broadcast releases internal condvar mutex before FUTEX_REQUEUE
operation, as otherwise the woken up thread most likely immediately sleeps
again on the internal condvar mutex until the broadcasting thread releases it.

Unfortunately this is racy and causes e.g.
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/nptl/tst-cond16.c?rev=1.1&content-type=text/x-cvsweb-markup&cvsroot=glibc
to hang on SMP.

http://listman.redhat.com/archives/phil-list/2004-May/msg00023.html contains
analysis how the hang happens, the problem is if any thread does
pthread_cond_*wait in between releasing of the internal condvar mutex and
FUTEX_REQUEUE operation, a wrong thread might be awaken (and immediately go to
sleep again because it doesn't satisfy conditions for returning from
pthread_cond_*wait) while the right thread requeued on the associated mutex
and there would be nobody to wake that thread up.

The patch below extends FUTEX_REQUEUE operation with something FUTEX_WAIT
already uses:

FUTEX_CMP_REQUEUE is passed an additional argument which is the expected value
of *futex.  Kernel then while holding the futex locks checks if *futex !=
expected and returns -EAGAIN in that case, while if it is equal, continues
with a normal FUTEX_REQUEUE operation.  If the syscall returns -EAGAIN, NPTL
can fall back to FUTEX_WAKE INT_MAX operation which doesn't have this problem,
but is less efficient, while in the likely case that nobody hit the (small)
window the efficient FUTEX_REQUEUE operation is used.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/linux/futex.h
kernel/compat.c
kernel/futex.c