Subject: Re: [boost] [thread] Timed waits in Boost.Thread potentiallyfundamentally broken on Windows (possibly rest of Boost too)
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-01-24 11:52:47
On 24 Jan 2015 at 18:01, Peter Dimov wrote:
> > If anyone has a problem with this solution, now is the time to speak.
> I do.
> The point of the timeout waits is that you have a deadline. On a
> non-realtime OS, this deadline can never be absolute, but it still makes no
> sense for the library to deliberately arrange things so that this deadline
> will never be met.
> You have no business changing the timeout value that the user has given you.
> Your task is to tell the kernel what the user wants. What the kernel does
> with this information is its own business and its responsibility.
> It's not just the size of the quantum that matters, but also where in the
> quantum the thread is at the moment it makes the sleep call. The kernel
> knows that it would make no sense to wake up a thread and then immediately
> context-switch away from it, so it arranges things to avoid this by either
> waking it up earlier, so that it has a portion of the quantum still
> available, or later, at the start of the next quantum. Sometimes 'earlier'
> is closer to what you asked, so it wakes you up earlier. This is exactly how
> it must be.
You may not be aware that Thread already substantially manipulates
the timeout sent to Windows. Firstly it converts any input
timeouts/deadlines into a steady_clock deadline. That enters the
Win32 implementation. This code then extracts a DWORD millisecond
timeout interval suitable for feeding to Windows. If that timeout is
20 ms or higher, it takes a code path based around deadline
scheduling kernel objects via CreateWaitableTimer. If that timeout is
19 ms or less it feeds it directly to the kernel wait composure
The problem with the above strategy is that it was clearly designed
around when Windows had a fixed tick interval of 10ms multiples, the
kernel didn't coalesce timers and the kernel wasn't tickless.
What I'm planning to do is very simple: we always use deadline timer
scheduling from now on, so quite literally the steady_clock deadline
that comes in is exactly that handed to Windows unmodified. I was
also going to try setting a tolerable delay via SetWaitableTimerEx()
on Vista and later where the tolerable delay is calculated as 10% of
the interval to the deadline but clamped to:
timeGetTime() <= tolerable delay <= 250 ms
So, no one is lying to the kernel, if anything I'm removing all lying
to the kernel and giving it more information with which to delay
timeouts. Would you find this acceptable?
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk