On Monday 05 May 2014 18:37:26 Niall Douglas wrote:
On 5 May 2014 at 17:26, Peter Dimov wrote:
The specification of condition variables allows spurious wakeups not because they can't be prevented by the implementation; it permits spurious wakeups to make client code assume spurious wakeups, because code that is written to assume spurious wakeups is more likely to be correct. Or conversely, code that does not assume spurious wakeups is likely to be incorrect even if no spurious wakeups occur.
I would have said spurious wakeups come exclusively from kernel bugs and the fact POSIX allows signals to escape syscalls, which is definitely a pre-threading era legacy design choice. On Windows spurious wakeups are trapped for you in user space so you never see them and therefore never have to deal with them, unless of course you elect to do so (e.g. any of the wait APIs able to return WAIT_IO_COMPLETION).
MSDN explicitly states that condition variables are subject to spurious wakeups: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682052(v=vs.85).as... With other APIs (including WaitFor* family) you do have to account for APC interruptions (as you said, by checking the result for WAIT_IO_COMPLETION value). So you are not relieved from spurious wakeups on Windows.
Spurious wakeups absolutely can be prevented by the implementation, just for backwards compatibility POSIX cannot do so.
AFAIR, the rationale for spurious wakeups is that preventing them would be too expensive for all uses of condition variables. Given that in most cases you need to check for a condition upon wakeup anyway, that added cost is a waste. That said, spurious wakeups can be concealed in some implementations. I think, on Linux libc is able to process EINTR returned from futex wait operations and conceal the wakeup without returning from pthread wait function.