Boost logo

Boost :

Subject: Re: [boost] [threads] API Design Question
From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2009-02-05 09:25:50


Alexander Bernauer wrote:
> I wasn't aware of the fact that it is not required to have the mutex
> acquired when calling notify_*.

I believe it is preferred to not have the lock held because you can
then have fewer context switches: if you notify with the lock held the
waiting thread may be scheduled but it will immediately block trying to
re-acquire the mutex, and the first thread will be scheduled again to
release it. I haven't measured the effect this though. Is anyone
aware of a correctness reason for not notifying with the lock held?

> AFAICS, in order to trigger the notification one has to acquire the lock
> anyway, because the waiting thread loops around some value of a state,
> which one has to alter concurrently.

Yes, i.e.

   lock mutex
   change state
   unlock mutex
   notify condition

> So, I can see no additional penalty when encapsulating spurious wakeups.

You have the penalty of actually doing the spuriousness check and
storing the extra state, as you described in your first post.

> I am aware of the wait functions, which accept a predicate and do the
> loop for you. My point is, that expressing the loop condition is not
> always trivial. Therefore in those cases - at least up to my experience
> - normaly new flags or counters are introduced, which signal "Yes, it
> was really intended that you woke up". This is cumbersome.

Can you give an example?

If your condition is very slow to evaluate and spurious wakeups are
common then you may save time by eliminating the possibility of
spuriousness before evaluating the condition. But my experience is
that spurious wakeups are rare in practice. (The exception might be if
your application makes a lot of use of signals, e.g. async IO or timers.)

> On the other hand those flags/counters are a safe way to solve the
> spurious wakeup problem in general. So why not having the library doing
> the job?

Well, it makes things slower for users whose conditions are simple or
who have infrequent spurious wakeups.

> Not to mention the fact that spurious wakeups are a very hard
> to detect bug in case one forgets to loop

Every instance of waiting on a condition should always be in a loop, or
use the predicate version of wait.

> or - even worse - there is a bug in the loop condition.

Regards, Phil.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk