Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming.threads > #184 > unrolled thread
| Started by | p6 c6d6 <p6c6d6@gmail.com> |
|---|---|
| First post | 2011-05-24 18:56 -0700 |
| Last post | 2011-05-31 14:07 -0700 |
| Articles | 19 — 5 participants |
Back to article view | Back to comp.programming.threads
cond signal wait p6 c6d6 <p6c6d6@gmail.com> - 2011-05-24 18:56 -0700
Re: cond signal wait Anthony Williams <anthony.ajw@gmail.com> - 2011-05-25 08:46 +0100
Re: cond signal wait p6 c6d6 <p6c6d6@gmail.com> - 2011-05-25 05:44 -0700
Re: cond signal wait Anthony Williams <anthony.ajw@gmail.com> - 2011-05-25 15:57 +0100
Re: cond signal wait p6 c6d6 <p6c6d6@gmail.com> - 2011-05-25 08:34 -0700
Re: cond signal wait Anthony Williams <anthony.ajw@gmail.com> - 2011-05-25 16:53 +0100
Re: cond signal wait Alexander Terekhov <terekhov@web.de> - 2011-05-25 19:16 +0200
Re: cond signal wait David Schwartz <davids@webmaster.com> - 2011-05-26 09:51 -0700
Re: cond signal wait Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-26 14:48 -0700
Re: cond signal wait David Schwartz <davids@webmaster.com> - 2011-05-26 23:20 -0700
Re: cond signal wait Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-27 14:50 -0700
Re: cond signal wait David Schwartz <davids@webmaster.com> - 2011-05-27 15:15 -0700
Re: cond signal wait Alexander Terekhov <terekhov@web.de> - 2011-05-28 15:48 +0200
Re: cond signal wait Alexander Terekhov <terekhov@web.de> - 2011-05-27 16:01 +0200
Re: cond signal wait David Schwartz <davids@webmaster.com> - 2011-05-27 12:34 -0700
Re: cond signal wait Alexander Terekhov <terekhov@web.de> - 2011-05-28 14:24 +0200
Re: cond signal wait David Schwartz <davids@webmaster.com> - 2011-05-29 01:33 -0700
Re: cond signal wait Alexander Terekhov <terekhov@web.de> - 2011-05-31 15:32 +0200
Re: cond signal wait David Schwartz <davids@webmaster.com> - 2011-05-31 14:07 -0700
| From | p6 c6d6 <p6c6d6@gmail.com> |
|---|---|
| Date | 2011-05-24 18:56 -0700 |
| Subject | cond signal wait |
| Message-ID | <bff468ff-45d7-4e18-8ff5-95238eb94585@c1g2000yqe.googlegroups.com> |
hi, what happens if a thread does a condition signal for a thread that has not yet done condition wait. is this not legitimate scenario, according to my limited experience in thread programming, i feel it is always possible. am i missing anything.or are there any ways to deterministically signal and wait. please shed some light. thanks
[toc] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-05-25 08:46 +0100 |
| Message-ID | <87aaebte7o.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #184 |
p6 c6d6 <p6c6d6@gmail.com> writes: > what happens if a thread does a condition signal for a thread that has > not yet done > condition wait. is this not legitimate scenario, according to my > limited experience in > thread programming, i feel it is always possible. am i missing > anything.or are there any > ways to deterministically signal and wait. please shed some light. If you signal a condition variable with no threads blocked in a waiting function then the signal has no effect. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | p6 c6d6 <p6c6d6@gmail.com> |
|---|---|
| Date | 2011-05-25 05:44 -0700 |
| Message-ID | <98cd47de-73d9-48e9-ac18-cc01cac1bb48@z7g2000prh.googlegroups.com> |
| In reply to | #186 |
On May 25, 12:46 pm, Anthony Williams <anthony....@gmail.com> wrote: > p6 c6d6 <p6c...@gmail.com> writes: > > what happens if a thread does a condition signal for a thread that has > > not yet done > > condition wait. is this not legitimate scenario, according to my > > limited experience in > > thread programming, i feel it is always possible. am i missing > > anything.or are there any > > ways to deterministically signal and wait. please shed some light. > > If you signal a condition variable with no threads blocked in a waiting > function then the signal has no effect. > > Anthony > -- > Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ > just::thread C++0x thread library http://www.stdthread.co.uk > Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk > 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 that is fine. but what if the thread which is suppose to recv the signal waits after the signal was delivered. doesn't it wait forever. let's assume a reader writer scenario. the writer writes one byte and waits for the reader to read and signal the writer. now if the writer writes some data and does a cond signal. during this time the reader was busy doing something else or didn't get a chance to run at all. now the reader waits on condition, and the signal was already lost. both reader and writer wait forever. isn't this a valid scenario. thanks
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-05-25 15:57 +0100 |
| Message-ID | <87lixubzfu.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #187 |
p6 c6d6 <p6c6d6@gmail.com> writes: > On May 25, 12:46 pm, Anthony Williams <anthony....@gmail.com> wrote: >> p6 c6d6 <p6c...@gmail.com> writes: >> > what happens if a thread does a condition signal for a thread that has >> > not yet done >> > condition wait. is this not legitimate scenario, according to my >> > limited experience in >> > thread programming, i feel it is always possible. am i missing >> > anything.or are there any >> > ways to deterministically signal and wait. please shed some light. >> >> If you signal a condition variable with no threads blocked in a waiting >> function then the signal has no effect. >> >> Anthony >> -- >> Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ >> just::thread C++0x thread library http://www.stdthread.co.uk >> Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk >> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 > > that is fine. but what if the thread which is suppose to recv the > signal > waits after the signal was delivered. doesn't it wait forever. Yes, if there is no-one waiting when the condvar was signalled, then the signal is ignored, and if the condvar is not subsequently signalled then any subsequent waiting threads will block forever, unless they use a timeout. > let's assume a reader writer scenario. the writer writes one byte and > waits for the reader to read and signal the writer. now if the writer > writes some data and does a cond signal. during this time the reader > was busy doing something else or didn't get a chance to run at > all. now the reader waits on condition, and the signal was already > lost. both reader and writer wait forever. isn't this a valid > scenario. Yes. However, if you hold the mutex that is associated with the cond var whilst signalling, then you can avoid this: if the signalling thread has the mutex then either (a) the waiting thread hasn't yet acquired the mutex to check if the data is ready, or (b) the waiting thread is blocked in the wait on the condvar. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | p6 c6d6 <p6c6d6@gmail.com> |
|---|---|
| Date | 2011-05-25 08:34 -0700 |
| Message-ID | <a05141df-cede-4929-9e8d-4b9394fd6858@22g2000prx.googlegroups.com> |
| In reply to | #188 |
On May 25, 7:57 pm, Anthony Williams <anthony....@gmail.com> wrote: > p6 c6d6 <p6c...@gmail.com> writes: > > On May 25, 12:46 pm, Anthony Williams <anthony....@gmail.com> wrote: > >> p6 c6d6 <p6c...@gmail.com> writes: > >> > what happens if a thread does a condition signal for a thread that has > >> > not yet done > >> > condition wait. is this not legitimate scenario, according to my > >> > limited experience in > >> > thread programming, i feel it is always possible. am i missing > >> > anything.or are there any > >> > ways to deterministically signal and wait. please shed some light. > > >> If you signal a condition variable with no threads blocked in a waiting > >> function then the signal has no effect. > > >> Anthony > >> -- > >> Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ > >> just::thread C++0x thread library http://www.stdthread.co.uk > >> Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk > >> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 > > > that is fine. but what if the thread which is suppose to recv the > > signal > > waits after the signal was delivered. doesn't it wait forever. > > Yes, if there is no-one waiting when the condvar was signalled, then the > signal is ignored, and if the condvar is not subsequently signalled then > any subsequent waiting threads will block forever, unless they use a > timeout. > > > let's assume a reader writer scenario. the writer writes one byte and > > waits for the reader to read and signal the writer. now if the writer > > writes some data and does a cond signal. during this time the reader > > was busy doing something else or didn't get a chance to run at > > all. now the reader waits on condition, and the signal was already > > lost. both reader and writer wait forever. isn't this a valid > > scenario. > > Yes. However, if you hold the mutex that is associated with the cond var > whilst signalling, then you can avoid this: if the signalling thread has > the mutex then either (a) the waiting thread hasn't yet acquired the > mutex to check if the data is ready, or (b) the waiting thread is > blocked in the wait on the condvar. > > Anthony > -- > Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ > just::thread C++0x thread library http://www.stdthread.co.uk > Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk > 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 > hasn't yet acquired the > mutex to check if the data is ready Ha! so, the key is the flag which specifies that the data is ready, before waiting on a condition variable the thread should always check if the work is already available if so there is no need to wait. > (a) the waiting thread hasn't yet acquired the > mutex to check if the data is ready, i didn't quiet get this point, holding the mutex just protects from the race for the flag and condition variable, it doesn't avoid the deadlock. thanks
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-05-25 16:53 +0100 |
| Message-ID | <87hb8ibwur.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #189 |
p6 c6d6 <p6c6d6@gmail.com> writes:
> On May 25, 7:57 pm, Anthony Williams <anthony....@gmail.com> wrote:
>> p6 c6d6 <p6c...@gmail.com> writes:
>> > let's assume a reader writer scenario. the writer writes one byte and
>> > waits for the reader to read and signal the writer. now if the writer
>> > writes some data and does a cond signal. during this time the reader
>> > was busy doing something else or didn't get a chance to run at
>> > all. now the reader waits on condition, and the signal was already
>> > lost. both reader and writer wait forever. isn't this a valid
>> > scenario.
>>
>> Yes. However, if you hold the mutex that is associated with the cond var
>> whilst signalling, then you can avoid this: if the signalling thread has
>> the mutex then either (a) the waiting thread hasn't yet acquired the
>> mutex to check if the data is ready, or (b) the waiting thread is
>> blocked in the wait on the condvar.
void waiter()
{
lock mutex; // **A**
while(!data ready) // loop to handle spurious wake-ups
wait on condvar; // **B** releases mutex
process data;
unlock mutex; // **C**
}
void signaller()
{
lock mutex;
// if we get here, waiter() hasn't yet executed **A**
// or is blocked in **B**, so will be woken by signal
// or has executed line **C** so doesn't care about signal
mark data as ready;
signal condvar;
unlock mutex;
}
Anthony
--
Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
just::thread C++0x thread library http://www.stdthread.co.uk
Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-05-25 19:16 +0200 |
| Message-ID | <4DDD3950.81DEDF32@web.de> |
| In reply to | #190 |
Anthony Williams wrote:
[...]
> void signaller()
> {
> lock mutex;
> // if we get here, waiter() hasn't yet executed **A**
> // or is blocked in **B**, so will be woken by signal
> // or has executed line **C** so doesn't care about signal
> mark data as ready;
> signal condvar;
> unlock mutex;
> }
lock mutex;
// if we get here, waiter() hasn't yet executed **A**
// or is blocked in **B**, so will be woken by signal
// or has executed line **C** so doesn't care about signal
mark data as ready;
unlock mutex;
signal condvar;
is the regular case.
signalling prior to unlock is special.
regards,
alexander.
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-05-26 09:51 -0700 |
| Message-ID | <f83d65a2-b249-43fb-84a0-195f88c90d56@18g2000prd.googlegroups.com> |
| In reply to | #189 |
On May 25, 8:34 am, p6 c6d6 <p6c...@gmail.com> wrote: > Ha! so, the key is the flag which specifies that the data is ready, > before waiting on a condition variable the thread should always check > if > the work is already available if so there is no need to wait. You'd have to be an idiot to wait for something that has already happened. > > (a) the waiting thread hasn't yet acquired the > > mutex to check if the data is ready, > i didn't quiet get this point, holding the mutex just protects from > the race for the flag > and condition variable, it doesn't avoid the deadlock. It does prevent the deadlock. The race is between the flag and the condition variable. Since you check the flag and start to wait while holding the mutex, the mutex prevents a race between the flag and the condition variable wait. The wait can only occur if the flag changes after you check the flag and decide to wait but before you actually start the wait. DS
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-05-26 14:48 -0700 |
| Message-ID | <8ab4e07e-2b9b-4375-b425-dc03e6d017d5@f15g2000pro.googlegroups.com> |
| In reply to | #189 |
On May 25, 8:34 am, p6 c6d6 <p6c...@gmail.com> wrote: > On May 25, 7:57 pm, Anthony Williams <anthony....@gmail.com> wrote: > > > > > > > > > > > p6 c6d6 <p6c...@gmail.com> writes: > > > On May 25, 12:46 pm, Anthony Williams <anthony....@gmail.com> wrote: > > >> p6 c6d6 <p6c...@gmail.com> writes: > > >> > what happens if a thread does a condition signal for a thread that has > > >> > not yet done > > >> > condition wait. is this not legitimate scenario, according to my > > >> > limited experience in > > >> > thread programming, i feel it is always possible. am i missing > > >> > anything.or are there any > > >> > ways to deterministically signal and wait. please shed some light. > > > >> If you signal a condition variable with no threads blocked in a waiting > > >> function then the signal has no effect. > > > >> Anthony > > >> -- > > >> Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ > > >> just::thread C++0x thread library http://www.stdthread.co.uk > > >> Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk > > >> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 > > > > that is fine. but what if the thread which is suppose to recv the > > > signal > > > waits after the signal was delivered. doesn't it wait forever. > > > Yes, if there is no-one waiting when the condvar was signalled, then the > > signal is ignored, and if the condvar is not subsequently signalled then > > any subsequent waiting threads will block forever, unless they use a > > timeout. > > > > let's assume a reader writer scenario. the writer writes one byte and > > > waits for the reader to read and signal the writer. now if the writer > > > writes some data and does a cond signal. during this time the reader > > > was busy doing something else or didn't get a chance to run at > > > all. now the reader waits on condition, and the signal was already > > > lost. both reader and writer wait forever. isn't this a valid > > > scenario. > > > Yes. However, if you hold the mutex that is associated with the cond var > > whilst signalling, then you can avoid this: if the signalling thread has > > the mutex then either (a) the waiting thread hasn't yet acquired the > > mutex to check if the data is ready, or (b) the waiting thread is > > blocked in the wait on the condvar. > > > Anthony > > -- > > Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ > > just::thread C++0x thread library http://www.stdthread.co.uk > > Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk > > 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 > > hasn't yet acquired the > > mutex to check if the data is ready > > Ha! so, the key is the flag which specifies that the data is ready, > before waiting on a condition variable the thread should always check > if > the work is already available if so there is no need to wait. > > > (a) the waiting thread hasn't yet acquired the > > mutex to check if the data is ready, > > i didn't quiet get this point, holding the mutex just protects from > the race for the flag > and condition variable, it doesn't avoid the deadlock. See Anthony Williams's post else-thread for the idiomatic way, and the way you should do it a majority of the time, and the default choice, for using condition variables. Note that actually the idiomatic way is to signal after the critical section instead of inside it (and definitely not before!!). Signalling inside the critical section doesn't break correctness, but it may (?) result in some additional work by the scheduler as it moves a thread from the cond wait state to the waiting for mutex state, and maybe (?) some additional context swaps, both of which are bad for performance. Also note how he uses "while" instead of "if" > while(!data ready) // loop to handle spurious wake-ups > wait on condvar; // **B** releases mutex This is required because of spurious wakeups with POSIX (and possibly other forms of condition variables). In POSIX condition variables, sometimes the waiter is woken up without a corresponding signal nor broadcast, randomly, for no particular reason. (Implementation detail.) That's why you need to recheck the shared data to see if there actually was a signal; hence "while" not "if".
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-05-26 23:20 -0700 |
| Message-ID | <c7b7a994-fb4d-4bf9-bb20-8bf9fceaa5b9@35g2000prp.googlegroups.com> |
| In reply to | #193 |
On May 26, 2:48 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote: > Also note how he uses "while" instead of "if" > > > while(!data ready) // loop to handle spurious wake-ups > > wait on condvar; // **B** releases mutex > > This is required because of spurious wakeups with POSIX (and possibly > other forms of condition variables). In POSIX condition variables, > sometimes the waiter is woken up without a corresponding signal nor > broadcast, randomly, for no particular reason. (Implementation > detail.) That's why you need to recheck the shared data to see if > there actually was a signal; hence "while" not "if". Even without spurious wakeups, it is usually still necessary. Consider: 1) Queue servicing threads A and B find the queue empty and block on the condition variable. 2) Thread C puts an object on the queue and calls pthread_cond_signal, waking thread A. 3) Thread D puts an object on the queue and calls pthread_cond_signal, waking thread B. 4) Thread A pulls the first object from the queue, process it. 5) Thread A re-acquires the mutex and checks the predicate. It finds the queue non-empty and pulls the second object from the queue. It releases the mutex to process the second object. 6) Thread B gets the CPU finally -- the queue is empty. The wakeup seems spurious. By the way, it is precisely this race that is the reason spurious wakeups are allowed by POSIX. The situation above is a problem that can only be resolved by checking the predicate after a wakeup. But condition variables have no predicate, they are stateless, so there is no good way the condition variable logic itself can prevent spurious wakeups. Only checking the predicate does that. DS
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-05-27 14:50 -0700 |
| Message-ID | <fb054ce9-8efe-4540-9cdd-cdfd0790ce3d@s16g2000prf.googlegroups.com> |
| In reply to | #195 |
On May 26, 11:20 pm, David Schwartz <dav...@webmaster.com> wrote: > On May 26, 2:48 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote: > > > Also note how he uses "while" instead of "if" > > > > while(!data ready) // loop to handle spurious wake-ups > > > wait on condvar; // **B** releases mutex > > > This is required because of spurious wakeups with POSIX (and possibly > > other forms of condition variables). In POSIX condition variables, > > sometimes the waiter is woken up without a corresponding signal nor > > broadcast, randomly, for no particular reason. (Implementation > > detail.) That's why you need to recheck the shared data to see if > > there actually was a signal; hence "while" not "if". > > Even without spurious wakeups, it is usually still necessary. Agreed. Depends on the design. In some rather contrived and simple designs, without spurious wakeups, you could get away with just an "if". I wouldn't suggest it. In an earlier draft of my post, I mentioned how it's also easier to reason about correctness with "while" instead of "true", but I trimmed it out. Apparently I should have kept it. > Consider: > > 1) Queue servicing threads A and B find the queue empty and block on > the condition variable. > 2) Thread C puts an object on the queue and calls pthread_cond_signal, > waking thread A. > 3) Thread D puts an object on the queue and calls pthread_cond_signal, > waking thread B. > 4) Thread A pulls the first object from the queue, process it. > 5) Thread A re-acquires the mutex and checks the predicate. It finds > the queue non-empty and pulls the second object from the queue. It > releases the mutex to process the second object. > 6) Thread B gets the CPU finally -- the queue is empty. The wakeup > seems spurious. > > By the way, it is precisely this race that is the reason spurious > wakeups are allowed by POSIX. The situation above is a problem that > can only be resolved by checking the predicate after a wakeup. But > condition variables have no predicate, they are stateless, so there is > no good way the condition variable logic itself can prevent spurious > wakeups. Only checking the predicate does that. Really? That doesn't seem to be an argument for spurious wakeups. That seems to be a good argument for using "while" instead of "if" by default. I thought that spurious wakeups were allowed because of signal handling. As best as I can remember, it goes something like: A thread is waiting on a condition variable. It receives a thread specific signal. Due to the details of how this is can be / commonly is implemented, the system call used to implement pthread_cond_wait will return EINTR after the thread is used to process the signal. The pthread_cond_wait cannot simply go back to waiting on the cond var because it might have lost a signal in the meantime, and thus it returns to the caller who can recheck invariants and decide if he needs to go back to waiting.
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-05-27 15:15 -0700 |
| Message-ID | <a014c2ff-7449-4010-b104-1a8ee6309eea@34g2000pru.googlegroups.com> |
| In reply to | #199 |
On May 27, 2:50 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote: > > By the way, it is precisely this race that is the reason spurious > > wakeups are allowed by POSIX. The situation above is a problem that > > can only be resolved by checking the predicate after a wakeup. But > > condition variables have no predicate, they are stateless, so there is > > no good way the condition variable logic itself can prevent spurious > > wakeups. Only checking the predicate does that. > Really? That doesn't seem to be an argument for spurious wakeups. That > seems to be a good argument for using "while" instead of "if" by > default. Except that the condition variable implementation *can't* use 'while' instead of 'if'. To use 'while', it would have to check the predicate, and the condition variable has no access to the predicate. The condition variable has no need for the 'if' because it waits unconditionally. This is why a standard for a stateless wait generally has no choice but to specify that spurious wakeups are possible. > I thought that spurious wakeups were allowed because of signal > handling. As best as I can remember, it goes something like: A thread > is waiting on a condition variable. It receives a thread specific > signal. Due to the details of how this is can be / commonly is > implemented, the system call used to implement pthread_cond_wait will > return EINTR after the thread is used to process the signal. The > pthread_cond_wait cannot simply go back to waiting on the cond var > because it might have lost a signal in the meantime, and thus it > returns to the caller who can recheck invariants and decide if he > needs to go back to waiting. It's the same point. If the condition variable code had access to the predicate, it could make a sensible decision of whether to repeat the wait or not. But since the condition variable implementation has no access to the predicate, the only sensible way to handle a case where there might have been a signal is to return. DS
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-05-28 15:48 +0200 |
| Message-ID | <4DE0FD20.8FA7464A@web.de> |
| In reply to | #200 |
David Schwartz wrote: [... "if" v. "while" ...] > It's the same point. If the condition variable code had access to the > predicate, it could make a sensible decision of whether to repeat the > wait or not. But since the condition variable implementation has no > access to the predicate, the only sensible way to handle a case where > there might have been a signal is to return. AFAIK, when Hoare invented condition variables he saw only signal (no broadcast) operation and "if" (not "while") for the wait with signalling done under protection of mutex (hand-off of mutex ownership from signaller to signallee akin to semas). Later, MESA folks introduced broadcast, changed "if" to "while", and allowed signalling without holding mutex. regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-05-27 16:01 +0200 |
| Message-ID | <4DDFAEC8.531D6882@web.de> |
| In reply to | #193 |
Joshua Maurice wrote: [...] > Note that actually the idiomatic way is to signal after the critical > section instead of inside it (and definitely not before!!). Signalling > inside the critical section doesn't break correctness, but it may (?) > result in some additional work by the scheduler as it moves a thread > from the cond wait state to the waiting for mutex state, and maybe (?) > some additional context swaps, both of which are bad for performance. Regarding question marks above: Simply put, signalling before unlock prolongs the duration of mutex lock time (signalling operation takes some time) and that is not good. That said, there are cases when condvar signalling must be done with locked mutex (e.g. when condvar may be destroyed by the other thread as the reaction to the predicate change). regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-05-27 12:34 -0700 |
| Message-ID | <2f847af0-7f62-43d2-aff3-f35f0d42c3ce@l2g2000prg.googlegroups.com> |
| In reply to | #197 |
On May 27, 7:01 am, Alexander Terekhov <terek...@web.de> wrote: > Simply put, signalling before unlock prolongs the duration of mutex lock > time (signalling operation takes some time) and that is not good. That's true, but there are many factors weighing the other way. The biggest one is that unlocking the mutex may wake up a thread that consumes the predicate, leading the subsequent signal to cause a spurious wakeup and two extra context switches. > That said, there are cases when condvar signalling must be done with > locked mutex (e.g. when condvar may be destroyed by the other thread as > the reaction to the predicate change). Yep. Another case is where unblocking the mutex may allow a new thread to block on the condition variable (as it will see the new predicate), causing the subsequent signal to wake up the wrong thread (not one that blocked on the old predicate), leading to a lost signal. DS
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-05-28 14:24 +0200 |
| Message-ID | <4DE0E997.42657B4A@web.de> |
| In reply to | #198 |
David Schwartz wrote: > > On May 27, 7:01 am, Alexander Terekhov <terek...@web.de> wrote: > > > Simply put, signalling before unlock prolongs the duration of mutex lock > > time (signalling operation takes some time) and that is not good. > > That's true, but there are many factors weighing the other way. The > biggest one is that unlocking the mutex may wake up a thread that > consumes the predicate, leading the subsequent signal to cause a Without wait-morphing, condvar signalling with mutex locked may cause a thread blocked on a condvar to wake up just to be blocked again now on mutex (after wake up due to condvar signalling). > spurious wakeup and two extra context switches. Context switching is old thinking. Nowadays think of idle multi(-core) processors hardware consuming electricity for no good reason instead of context switching: assume that all threads can run in parallel (simultaneously) and that unblocking blocked threads can never impact performance negatively. regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-05-29 01:33 -0700 |
| Message-ID | <38011e68-82bb-4ca5-af04-009c2d750e17@q12g2000prb.googlegroups.com> |
| In reply to | #202 |
On May 28, 5:24 am, Alexander Terekhov <terek...@web.de> wrote: > Without wait-morphing, condvar signalling with mutex locked may cause a > thread blocked on a condvar to wake up just to be blocked again now on > mutex (after wake up due to condvar signalling). If you're going to assume an implementation handles X badly and Y well, then Y is better. If you assume it handles Y badly and X well, then X is better. If you're going to compare X to Y in an implementation-neutral context, you have to assume that the implementation doesn't do anything particularly stupid. > > spurious wakeup and two extra context switches. > Context switching is old thinking. Nowadays think of idle multi(-core) > processors hardware consuming electricity for no good reason instead of > context switching: assume that all threads can run in parallel > (simultaneously) and that unblocking blocked threads can never impact > performance negatively. If that's the case, why care about performance since there's clearly tons of CPU to spare? Quite the contrary, the case in which you care about performance is when all the cores are doing useful work and a wasted context switch ejects a useful task and blows away its caches. DS
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-05-31 15:32 +0200 |
| Message-ID | <4DE4EDD9.7B27185A@web.de> |
| In reply to | #204 |
David Schwartz wrote: [...] > If that's the case, why care about performance since there's clearly > tons of CPU to spare? Quite the contrary, the case in which you care > about performance is when all the cores are doing useful work and a > wasted context switch ejects a useful task and blows away its caches. You didn't get me: I'm taking about the case with no context switching/no ejected threads due to blocking (i.e. there is nothing to blow away). IOW, assume that you just can't perceive the effect of (supposed) context switching. regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | David Schwartz <davids@webmaster.com> |
|---|---|
| Date | 2011-05-31 14:07 -0700 |
| Message-ID | <a0ed82d4-ff25-4a6d-ad8d-037cbc9c2d8e@r33g2000prh.googlegroups.com> |
| In reply to | #210 |
On May 31, 6:32 am, Alexander Terekhov <terek...@web.de> wrote: > You didn't get me: I'm taking about the case with no context > switching/no ejected threads due to blocking (i.e. there is nothing to > blow away). > > IOW, assume that you just can't perceive the effect of (supposed) > context switching. I don't see how that case is realistic in any situation in which you care about performance. If the CPU is sitting idle doing nothing, that means either the software is horribly designed (which means nobody cares about performance) or there's very little work to do (in which case, nobody cares about performance). You only care about performance when the software is optimized for performance and there is lots of work to do. DS
[toc] | [prev] | [standalone]
Back to top | Article view | comp.programming.threads
csiph-web