
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 routine. 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? Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/