diff --git a/stl/inc/thread b/stl/inc/thread index 0b66acf296..83b2c62473 100644 --- a/stl/inc/thread +++ b/stl/inc/thread @@ -197,9 +197,16 @@ namespace this_thread { return; } - _timespec64 _Tgt; - (void) _To_timespec64_sys_10_day_clamped(_Tgt, _Abs_time - _Now); - _Thrd_sleep(&_Tgt); + // _Clamp must be less than 2^32 - 1 (INFINITE) milliseconds, but is otherwise arbitrary. + constexpr chrono::milliseconds _Clamp{chrono::hours{24}}; + + const auto _Rel = _Abs_time - _Now; + if (_Rel >= _Clamp) { + _Thrd_sleep_for(static_cast(_Clamp.count())); + } else { + const auto _Rel_ms = chrono::ceil(_Rel); + _Thrd_sleep_for(static_cast(_Rel_ms.count())); + } } } diff --git a/stl/inc/xthreads.h b/stl/inc/xthreads.h index 26302f0aea..6ebc4e90f1 100644 --- a/stl/inc/xthreads.h +++ b/stl/inc/xthreads.h @@ -83,10 +83,10 @@ enum class _Thrd_result : int { _Success, _Nomem, _Timedout, _Busy, _Error }; // threads _CRTIMP2_PURE _Thrd_result __cdecl _Thrd_detach(_Thrd_t); _CRTIMP2_PURE _Thrd_result __cdecl _Thrd_join(_Thrd_t, int*); -_CRTIMP2_PURE void __cdecl _Thrd_sleep(const _timespec64*); _CRTIMP2_PURE void __cdecl _Thrd_yield(); _CRTIMP2_PURE unsigned int __cdecl _Thrd_hardware_concurrency(); _CRTIMP2_PURE _Thrd_id_t __cdecl _Thrd_id(); +void __stdcall _Thrd_sleep_for(unsigned long /*ms*/) noexcept; // mutexes enum { // mutex types diff --git a/stl/src/cthread.cpp b/stl/src/cthread.cpp index 618037bbfd..75f4426e14 100644 --- a/stl/src/cthread.cpp +++ b/stl/src/cthread.cpp @@ -73,6 +73,7 @@ _CRTIMP2_PURE _Thrd_result __cdecl _Thrd_detach(_Thrd_t thr) { return CloseHandle(thr._Hnd) ? _Thrd_result::_Success : _Thrd_result::_Error; } +// TRANSITION, ABI: _Thrd_sleep() is preserved for binary compatibility _CRTIMP2_PURE void __cdecl _Thrd_sleep(const _timespec64* xt) { // suspend thread until time xt _timespec64 now; _Timespec64_get_sys(&now); diff --git a/stl/src/sharedmutex.cpp b/stl/src/sharedmutex.cpp index 6cfcc63cf4..c013e7776f 100644 --- a/stl/src/sharedmutex.cpp +++ b/stl/src/sharedmutex.cpp @@ -36,4 +36,8 @@ void __cdecl _Smtx_unlock_exclusive(_Smtx_t* smtx) { // unlock exclusive shared void __cdecl _Smtx_unlock_shared(_Smtx_t* smtx) { // unlock non-exclusive shared mutex ReleaseSRWLockShared(reinterpret_cast(smtx)); } + +void __stdcall _Thrd_sleep_for(const unsigned long ms) noexcept { // suspend current thread for `ms` milliseconds + Sleep(ms); +} }