Boost logo

Boost :

Subject: Re: [boost] [thread] Timed waits in Boost.Thread potentially fundamentally broken on Windows (possibly rest of Boost too)
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2015-01-23 08:46:29


On Friday 23 January 2015 13:23:48 Niall Douglas wrote:
> On 23 Jan 2015 at 15:35, Andrey Semashev wrote:
> > > Option 2: We loop waiting until steady_clock (really
> > > QueryPerformanceCounter under Boost) shows the requested timeout has
> > > passed. Problem: This wastes battery power and generates needless
> > > wakeups. A more intelligent implementation would ask Windows for the
> > > thread quanta and transform timeouts to match the Vista kernel
> > > scheduler in combination with always using deadline scheduling, but
> > > this would slow down the timed waits implementation.
> >
> > That is a missed notification waiting to happen.
>
> For reference for those pondering this option, there is no
> possibility of missed notifications on Windows as unless you use
> PulseEvent() (we don't), it can't happen on the win32 threading
> model.

There is, if a spurious wakeup happens. There is a window between returning
from a wait function and re-locking the mutex. If you loop without checking
for a condition, notifications in that window will be missed.

> > > Option 3: We adjust Boost.Thread to return timeouts when Windows
> > > returns a timed out status code, even if the actual time waited is
> > > considerably lower than the time requested. Problem: some code
> > > written for POSIX where when you ask for a timeout you always get it
> > > may misbehave in this situation.
> >
> > That is simply incorrect. Why would you indicate a timeout when none
> > occurred? This will surely break some timed code.
>
> Some would say that if Windows claims a timeout, we should return a
> timeout. I suspect this is what the Dinkumware STL will do, and for
> compatibility we may wish to match that.

We're not mimicking OS behavior in Boost.Thread - that's the point of it being
a portability layer. The library implements standard C++ components and as
such should behave as close to the standard as possible. If Windows is not
well suited for it then oh well... MS should fix Windows then to be more
efficient.

> > The standard description is pretty clear: return cv_status::timeout only
> > when the timeout has expired, otherwise return cv_status::no_timeout.
> > Boost.Thread should follow this.
>
> This is the current behaviour. However, and it is a big however, the
> semantics are subtly different. On POSIX you either get your wait as
> long as you asked or a spurious wakeup. On Windows you are ordinarily
> getting a wait between nothing and an arbitrary higher amount than
> requested. This is a "spurious wakeup on steroids".

I don't see the difference. On POSIX, you're not guaranteed to be woken up
exactly at the timeout either. And spurious wakeups can potentially happen as
often as one can emit signals to the process. Granted, that usually doesn't
happen that often, but conceptually this is not different from Windows.

> The key point here is that Windows spurious wakeups are occuring
> *much* more frequently than on POSIX. This has implications for
> battery life and plenty more.

So we're talking about efficiency, not correctness as you originally stated?


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