public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "mihaylov.mihail at gmail dot com" <sourceware-bugzilla@sourceware.org>
To: glibc-bugs@sources.redhat.com
Subject: [Bug nptl/13165] pthread_cond_wait() can consume a signal that was sent before it started waiting
Date: Sun, 25 Sep 2011 21:33:00 -0000	[thread overview]
Message-ID: <bug-13165-131-rAb9iXzr0E@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-13165-131@http.sourceware.org/bugzilla/>

http://sourceware.org/bugzilla/show_bug.cgi?id=13165

--- Comment #5 from Mihail Mihaylov <mihaylov.mihail at gmail dot com> 2011-09-25 21:32:35 UTC ---
Created attachment 5945
  --> http://sourceware.org/bugzilla/attachment.cgi?id=5945
Test to observe the race

Attaching a self contained test. What the test does:

We have a mutex and a condition variable. We also have several auxiliary
condition variables and counters.

The main thread locks the mutex and creates as many waiter threads as possible.
The waiter threads start by waiting on the mutex. Then both the main thread and
the waiter thread start looping to perform iterations of the test until the
race condition in NPTL is hit.

The loops of the main thread and the waiter threads are synchronized and go
like this:

1) The main thread starts by releasing the mutex and blocking on an auxiliary
condvar. This unblocks the waiter threads which start by entering the first
wait on the condition variable. Each waiter thread increments a waiters counter
before waiting and the last one also signals the auxiliary condvar to notify
the main thread that all waiters are blocked on the first wait.

2) When all waiters are blocked on the first wait, the main thread is unblocked
and starts sending signals. It sends as many signals as there are waiters, so
all waiters should move (eventually) beyond the first wait. The main thread
holds the mutex while sending the signals. The 'releaseMutexBetweenSignals'
constant controls whether it will release and reacquire the mutex between
signals.

3) Each unblocked waiter decrements the waiters counter and moves to the second
wait. To simplify the test, the waiters don't enter the second wait until all
signals from step 2 have been sent. This is controlled through a sent signals
counter and another auxiliary condvar.

4) After the main thread has sent all signals, it starts waiting for at least
two waiters to block on the second wait. This is facilitated by a counter of
the threads that have reached the second wait and one more auxiliary condvar.

5) When at least two threads have blocked on the second wait, the main thread
sends one more signal. Threads that get unblocked from the second wait may
start a third wait to allow the test iteration to complete before they loop
back to the first wait (of course this actually happens when the main thread
releases the mutex in step 6)

6) The main thread starts waiting for all waiters to exit the first wait. Each
waiter that exits the first wait decrements the waiters count and the last one
signals the last auxiliary condvar that the main thread waits on. If the wait
times out, the test has failed, otherwise it has passed.

7) If the test has passed, all waiters are waiting on the condition variable in
the second wait or the third wait, so the main thread sends a broadcast to
unblock them and all waiters move back to the first wait. With this the test
iteration is complete and a new iteration begins.


The main point about this test is that at the point where the main thread sends
the single signal, all waiters should be:

1) either waiting on the mutex in the first wait,
2) or waiting on the condition variable in the second wait,
3) or waiting on the mutex in the wait on the auxiliary condvar from step 3

which means that if the mutex gets released for long enough, all threads should
acquire the mutex in the first wait and the waiters count should eventually
reach zero. Step 6 is meant to provide this time. At step 6, the main thread
releases the mutex and starts waiting, and all waiters that acquire the mutex
release it almost immediately and start waiting themselves, so there is nothing
to prevent the threads from group (1) above from acquiring the mutex one by one
and bringing the waiters counter back to 0. The only thing that can get in the
way is if there is a waiter which is still blocked on the condition variable in
the first wait, which is what the test aims to trigger and detect.

-- 
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.


  parent reply	other threads:[~2011-09-25 21:33 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-07 19:15 [Bug nptl/13165] New: " mihaylov.mihail at gmail dot com
2011-09-21  9:12 ` [Bug nptl/13165] " mihaylov.mihail at gmail dot com
2011-09-21 18:19 ` bugdal at aerifal dot cx
2011-09-21 22:29 ` bugdal at aerifal dot cx
2011-09-22 22:21 ` mihaylov.mihail at gmail dot com
2011-09-25 21:33 ` mihaylov.mihail at gmail dot com [this message]
2011-09-25 21:44 ` mihaylov.mihail at gmail dot com
2011-09-26  9:27 ` mihaylov.mihail at gmail dot com
2011-09-26 16:20 ` bugdal at aerifal dot cx
2011-09-27 10:10 ` mihaylov.mihail at gmail dot com
2011-09-27 10:13 ` mihaylov.mihail at gmail dot com
2011-09-28  2:07 ` bugdal at aerifal dot cx
2011-09-28  2:08 ` bugdal at aerifal dot cx
2011-09-28  9:03 ` mihaylov.mihail at gmail dot com
2011-09-28 16:06 ` bugdal at aerifal dot cx
2011-09-28 21:00 ` mihaylov.mihail at gmail dot com
2012-09-19 15:15 ` triegel at redhat dot com
2012-09-19 15:21 ` triegel at redhat dot com
2012-09-19 17:23 ` bugdal at aerifal dot cx
2012-09-20 10:28 ` mihaylov.mihail at gmail dot com
2012-09-20 10:43 ` triegel at redhat dot com
2012-09-20 11:05 ` mihaylov.mihail at gmail dot com
2012-09-20 11:23 ` triegel at redhat dot com
2012-09-20 11:58 ` triegel at redhat dot com
2012-09-20 12:46 ` mihaylov.mihail at gmail dot com
2012-09-20 12:49 ` mihaylov.mihail at gmail dot com
2012-09-20 16:21 ` triegel at redhat dot com
2012-09-20 18:39 ` bugdal at aerifal dot cx
2012-09-20 19:48 ` mihaylov.mihail at gmail dot com
2012-09-20 20:31 ` bugdal at aerifal dot cx
2012-09-21  8:04 ` triegel at redhat dot com
2012-09-21  8:05 ` siddhesh at redhat dot com
2012-09-21  8:54 ` bugdal at aerifal dot cx
2012-09-21 15:45 ` triegel at redhat dot com
2012-10-18  6:26 ` mihaylov.mihail at gmail dot com
2012-10-18 12:25 ` bugdal at aerifal dot cx
2012-10-24 20:26 ` triegel at redhat dot com
2012-10-25  4:08 ` bugdal at aerifal dot cx
2013-01-19 16:19 ` scot4spam at yahoo dot com
2014-02-16 17:45 ` jackie.rosen at hushmail dot com
2014-03-28  9:23 ` dancol at dancol dot org
2014-05-28 19:44 ` schwab at sourceware dot org
2014-06-27 12:09 ` fweimer at redhat dot com
2014-08-18 21:22 ` triegel at redhat dot com
2014-08-18 21:42 ` bugdal at aerifal dot cx
2015-08-26 15:29 ` kkersten at cray dot com
2017-01-01 21:32 ` triegel at redhat dot com

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-13165-131-rAb9iXzr0E@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=glibc-bugs@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).