-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<thread>: this_thread::sleep_until uses system time even if based on steady_clock #718
Comments
Yep, this is a known bug that affects bincompat, thanks for reporting it. |
After 5 minutes of additional thought, we've realized that this might be fixable by adding new functions to the import library (without changing the behavior of the DLL, which must remain unchanged for previously compiled code). We hadn't considered this solution before, for the thread sleep issue, despite using the import lib for other features/fixes. 🧠 |
My observations here:
|
Is sounds more like a Standard defect to me. Standard defines this hard to implement feature, but acknowledges it is not useful:
|
So here are three functions that needs to be replaced with other functions:
Apparently they can be re-implemented in a new translation unit injected into the import library. New functions could be made taking either time point relative to Duration can be |
AFAIK they can't be implemented in the import library because we might choose ConcRT backing for the synchronization primitives, and ConcRT depends on global state in the STL and ConcRT DLLs that will be damaged trying to do this from outside. Fixing I recommend just waiting until we can do all the vNext things though. Sleeping a thread isn't a super useful tool anyway. |
I think the use of |
I believe NtWaitForSingleObject is documented: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-zwwaitforsingleobject |
It is driver kit, not SDK. In theory it might mean higher risk for this to be broken in future OS. In practice I don't think so, not at least for this function. |
I actually don't get this problem. Say there's exactly the same function as |
The implementation of the new function needs to do waits / wake waiters / etc. in a way that existing .objs that don't call the new function aren't broken. I don't know exactly how the ConcRT backend works but I'm pretty sure it has some globals that will be inaccessible from the import library. |
I think you are referring to this: Lines 22 to 45 in 0cbd1b2
Lines 288 to 316 in 0cbd1b2
These APIs are already in relative units. |
In fact the decision is made when |
If you can get it to work I'm not going to dispute an existence proof |
Any update on this? We've run into this issue |
Not from me. I'm not interested in contributing a fix or other changes in near time. Although due to cleanup in mutexes area recently performed by @StephanTLavavej and me, there's no more |
Actually I think @BillyONeal would not question my idea anymore, as his concern was ConCRT:
and like I said, it was ConCRT case was recently wiped out. But it is fixable, possibly if you want the fix that much, you can contribute it.... |
Is there any actual need for waiting on the current thread with a timeout given that waitable timers exist and work with relative and absolute times with 100ns precision? https://docs.microsoft.com/en-us/windows/win32/sync/using-waitable-timer-objects shows the basic idea. It's all documented Win32 stuff, so no need to use NtXxx and ZwXxx functions. This is the approach used in OpenThreads for microsecond-precise sleeps: https://github.com/openscenegraph/OpenSceneGraph/blob/master/src/OpenThreads/win32/Win32Thread.cpp#L670-L698 Using that would fix the resolution issues caused by using millisecond-precise |
Creating waitable timers can fail, but this_thread::sleep_for can't.
The kernel does not provide microsecond sleeps in any form, even though there are some APIs that accept
Just because the API accepts better than milliseconds doesn't mean that the kernel scheduler will ever give that to you. |
Fair enough. |
Any update on this? It's unfortunate that there's not even a workaround using STL. Workarounds are to use Boost (tested with 1.67) or the Win32 API directly. |
Any update on this? |
When will it be fixed? |
It is already fixed for |
Describe the bug
Internally,
sleep_until
calls_To_xtime_10_day_clamped
to convert time point of any clock to time point of System clock. Then_Thrd_sleep
sleeps on this system time point:STL/stl/inc/thread
Lines 154 to 166 in 3141965
_To_xtime_10_day_clamped
usessystem_clock
STL/stl/inc/chrono
Lines 629 to 652 in 3141965
If
system_clock
is adjusted between_To_xtime_10_day_clamped
and_Thrd_sleep
, the sleep interval is wrong.sleep_for
is also subject to this problem as it is based onsleep_until
STL/stl/inc/thread
Lines 168 to 171 in 3141965
Though standard says
Command-line test case
Hard to build stable repro, but will try if needed.
Expected behavior
Neither
sleep_until
relative to a steady clock norsleep_for
should depend onsystem_clock
.GetTickCount64
is good enough steady clock, asSleep
API does not have granularity less than a millisecond anyway (calling undocumentedNtDelayExecution
is unacceptable).GetTickCount64
is very fast clock, it is basically reading a global variable.STL version
Additional context
Suspect that tests for #593 are failing due to timeout because other tests simultaneously tamper with system clock.Ok, this theory is defeated now, but the bug still looks validThe text was updated successfully, but these errors were encountered: