-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
bugSomething isn't workingSomething isn't workingchronoC++20 chronoC++20 chronofixedSomething works now, yay!Something works now, yay!
Description
Originally reported as DevCom-10913616 / VSO-2495823.
My cleaned-up repro:
C:\Temp>type meow.cpp
#include <chrono>
#include <print>
#include <semaphore>
#include <stop_token>
#include <thread>
using namespace std;
using namespace std::chrono;
void f(stop_token stop) {
binary_semaphore new_timer{0};
for (int i = 0; i < 50 && !stop.stop_requested(); ++i) {
const auto s = steady_clock::now();
(void) new_timer.try_acquire_for(800us);
const auto e = steady_clock::now();
println("{}", duration_cast<nanoseconds>(e - s));
}
}
int main() {
jthread t(f);
this_thread::sleep_for(1s);
}C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MT /O2 meow.cpp
meow.cpp
C:\Temp>meow
200ns
100ns
0ns
0ns
0ns
0ns
100ns
0ns
[...]
I haven't fully analyzed this, but I observe that we still have some calls to GetTickCount64(), which IIRC uses the system clock instead of a steady clock:
Lines 180 to 207 in 7841cf8
| unsigned long long __stdcall __std_atomic_wait_get_deadline(const unsigned long long _Timeout) noexcept { | |
| if (_Timeout == _Atomic_wait_no_deadline) { | |
| return _Atomic_wait_no_deadline; | |
| } else { | |
| return GetTickCount64() + _Timeout; | |
| } | |
| } | |
| unsigned long __stdcall __std_atomic_wait_get_remaining_timeout(unsigned long long _Deadline) noexcept { | |
| static_assert(__std_atomic_wait_no_timeout == INFINITE, | |
| "__std_atomic_wait_no_timeout is passed directly to underlying API, so should match it"); | |
| if (_Deadline == _Atomic_wait_no_deadline) { | |
| return INFINITE; | |
| } | |
| const unsigned long long _Current_time = GetTickCount64(); | |
| if (_Current_time >= _Deadline) { | |
| return 0; | |
| } | |
| unsigned long long _Remaining = _Deadline - _Current_time; | |
| constexpr unsigned long _Ten_days = 864'000'000; | |
| if (_Remaining > _Ten_days) { | |
| return _Ten_days; | |
| } | |
| return static_cast<unsigned long>(_Remaining); | |
| } |
🛠️ Previous fixes for this category of bugs
The other uses of GetTickCount64() in sharedmutex.cpp appear to be properly "checked" in the headers against steady_clock or the user's clock. This is after the series of fixes:
- VS 2022 17.9: Make
this_thread::sleep_untilclock-aware #3914- Fixed
this_thread::sleep_until()to consistently use the giventime_point's clock type, instead of also depending on the system clock. This also fixedthis_thread::sleep_for()to consistently usesteady_clock.
- Fixed
- VS 2022 17.11: Wait on condition variables independently on system time #4457
- Fixed
condition_variable::wait_until()andcondition_variable_any::wait_until()to consistently use the giventime_point's clock type, instead of also depending on the system clock. This also fixedcondition_variable::wait_for()to consistently usesteady_clock.
- Fixed
- VS 2022 17.12: Wait
condition_variable_anyforsteady_clock#4755`- Fixed
condition_variable_any::wait_for()to consistently usesteady_clock.
- Fixed
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingchronoC++20 chronoC++20 chronofixedSomething works now, yay!Something works now, yay!