Haiku's (Kernel) Condition Variables API: Design & Implementation | Haiku Project

A few months after my contract with Haiku, Inc. began, I rewrote the implementation of the Haiku kernel’s condition variables (as opposed to our userspace condition variables, which are from POSIX.) As this new implementation has run in Haiku for over a year and shipped in the latest release with no sign of any remaining issues, I figured it is high time for a deep-dive on the API, its implementation history, and the design of the new implementation I wrote.

This is a companion discussion topic for the original entry at https://www.haiku-os.org/blog/waddlesplash/2023-04-24_condition_variables/


i skimmed through the blog post, did Waddlesplash just turn haiku into a real rtos with this change ???

i could use interrupts to trigger calculations, with wait, if so, this is a massive change for low latency rtos needs.
.i need to read more on this

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())
		T data(fMessageQueue.front());
        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.


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

My apologies, I wanted to say spurious wakeup (instead of interrupt). Spurious wakeup - Wikipedia

Right, but either way, it’s still got nothing to do with underlying CPU behavior; scheduling decisions are taken entirely at the OS or library level, not the CPU.

That was a very informative insight into kernel development,thanks :+1:
I can’t say that I did even understand half of it,as I’m mostly experienced with web development which works fundamentally different.
Still I always enjoy reading some details about how the software I use everyday works internally.


wether you intended to make a more rtos type kernel or not, your current design choices have certainly opened doors for rtos concepts and control systems.

good job