This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug nptl/12875] New: pthread_cond_timedwait can steal the wakeup of slower thread in pthread_cond_wait
- From: "martin at lispworks dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: Fri, 10 Jun 2011 17:57:26 +0000
- Subject: [Bug nptl/12875] New: pthread_cond_timedwait can steal the wakeup of slower thread in pthread_cond_wait
- Auto-submitted: auto-generated
http://sourceware.org/bugzilla/show_bug.cgi?id=12875
Summary: pthread_cond_timedwait can steal the wakeup of slower
thread in pthread_cond_wait
Product: glibc
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: nptl
AssignedTo: drepper.fsp@gmail.com
ReportedBy: martin@lispworks.com
Created attachment 5787
--> http://sourceware.org/bugzilla/attachment.cgi?id=5787
Example source code
According to the definition of pthread_cond_signal, it should only unblock
threads that are blocked at the time it is called.
The attached example demonstrates a bug in pthread_cond_timedwait that can
allow it to "steal" the signal from a thread that was blocked in
pthread_cond_wait when pthread_cond_signal was called, even though
pthread_cond_timedwait was called after pthread_cond_signal.
This was tested on an Intel Core i7 970 CPU (6 cores, 12 threads) running
Fedora 14 x86_64 with the master branch of glibc from 2011-06-10 and also with
older releases.
There is no easy way to repeat this, because it depends very much on the timing
of the threads, so I've had to cheat by using pthread_kill to artificially
delay the thread that called pthread_cond_wait (cs_ptA).
The expected output of the program is
A waits
cs_timewaster starts
B signals
cs_delaywaster starts
C waits
D waits
B signals
C wakes
D wakes with ETIMEDOUT
cs_delaywaster ends
A wakes
Note that D wakes with ETIMEDOUT and A wakes afterwards.
Often the program hangs after outputing
A waits
cs_timewaster starts
B signals
cs_delaywaster starts
C waits
D waits
B signals
C wakes
D wakes with code 0
cs_delaywaster ends
Note that D wakes with code 0 and A never wakes.
The calls to usleep in the example are such that the first signal from thread B
should cause thread A to wake and second signal should cause thread C to wake.
Thread D should wake on the timeout.
I think the problem is that if thread A wakes from the futex but doesn't
execute the rest of pthread_cond_wait quickly enough (e.g. because the signal
handler cs_delaywaster runs), then thread D can steal the wakeup when its futex
returns on the timeout.
--
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.