
On Thursday 05 February 2009 15:25:50 Phil Endecott wrote:
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 checked the posix documentation and indeed it is not guaranteed that the above does not happen. I didn't expect that.
I haven't measured the effect this though.
Maybe some implementations are smart enough to avoid this scenario. At least I hope so.
Can you give an example?
In my case, I have two event queues. One for immediate events and one for delayed ones, i.e. something like std::queue<Event*> imQ; std::priority_queue<std::pair<system_time, Event*> > delQ; Both queues are encapsulated by a "meta"-queue class providing void push(Event*, time_duration delay=not_a_date_time) and Event* pop() Besides normal queue semantics the meta queue has the additional constraint that a delayed event may not be returned by pop() before its delivery time has been reached. Without spurious wakeups, we would have ---8<--- void push(Event* event, time_duration delay=not_a_date_time) { lock l(mutex); if (delay == not_a_date_time) { imQ.push(event); } else { delQ.push(std::make_pair(get_system_time() + delay, event)); } condition.notify(); } --->8--- and ---8<--- Event* pop() { lock l(mutex); while(1) { if (not imQ.emtpy()) { Event* event = imQ.top(); imQ.pop(); return event; } else { if (not delQ.empty()) { const system_time now = get_system_time(); if (delQ.top().first < now) { Event* event = delQ.top().second; delQ.pop(); return event; } else { condition.timed_wait(l, delQ.top().first); // (1) } } else { condition.wait(l); // (2) } } } } --->8--- While writing those lines I realized that the above code is correct even if there are spurious wakeups. My point was that (1) becomes ---8<--- while (imQ.empty() and get_system_time() < delQ.top().first and condition.timed_wait(l, delQ.top().first)); --->8--- and (2) becomes ---8<--- while(imQ.empty() and delQ.empty()) { condition.wait(); } --->8--- but this is not necessary. Maybe the above is a general pattern to avoid complicated loop conditions for spurious wakeups. If this is true, besides convenience, I have no argument left for encapsulating spurious wakeups. Thank you regards Alexander