This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nptl/12875] New: pthread_cond_timedwait can steal the wakeup of slower thread in pthread_cond_wait


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]