Thank you waddlesplash for an informative article. I’ve used boost::condition variables in the past (pre C++11 codebases and up) and believe it or not, actually had to cater for spurious interrupts (it’s mind boggling that this is actually necessary, however the CPU designers have their reasons). Just because the condition.wait(lock) operation completes, it doesn’t mean that the actual condition was signaled. Most developers have code similar to the following:
T PopWait()
{
boost::mutex::scoped_lock lock(fMutex);
while (fMessageQueue.empty())
{
fAvailable.wait(lock);
}
T data(fMessageQueue.front());
fMessageQueue.pop();
return data;
}
I’ve personally moved away from condition variables in newer code bases and use the Actor model for multiprocessing. The underlying runtime only uses std::counting_semaphores and spinlocks, in a combination familiar to all BeOS users - Benaphores. Works a treat. BeAPI is also good since it allows releasing semaphore without an immediate process reschedule, so when pushing a message the current task continues running.
Edit: should be spurious wakeup
Thank you for the article.
1 replyNo. This change improves synchronization overhead on multicore systems, but it doesn’t fundamentally alter scheduling models or thread synchronization approaches.
Spurious condition variable wakeups have nothing to do with CPU designs in the kernel, and even less so in userland. This is/was probably indicative of some kind of bug in Boost, or even in the underlying OS, but not in the CPU.
1 replyMy apologies, I wanted to say spurious wakeup (instead of interrupt). Spurious wakeup - Wikipedia
1 reply