pipeline: Use a high-precision timer for Thread::sleep() on Win32

This is mainly used for clock mode M_limited, which is currently suffering from terrible imprecision on Windows.  This fixes that, making it possible to lower the value of sleep-precision down to 1ms.
This commit is contained in:
rdb 2024-09-16 21:42:28 +02:00
parent bb5e4454fe
commit b337f2a3da
3 changed files with 28 additions and 9 deletions

View File

@ -63,14 +63,6 @@ is_simple_threads() {
return false;
}
/**
*
*/
INLINE void ThreadWin32Impl::
sleep(double seconds) {
Sleep((int)(seconds * 1000));
}
/**
*
*/

View File

@ -78,6 +78,11 @@ ThreadWin32Impl::
}
CloseHandle(_thread);
if (_timer != nullptr) {
CloseHandle(_timer);
_timer = nullptr;
}
}
/**
@ -200,6 +205,27 @@ bind_thread(Thread *thread) {
return thread;
}
/**
*
*/
void ThreadWin32Impl::
sleep(double seconds) {
Thread *thread = get_current_thread();
ThreadWin32Impl *self = &thread->_impl;
HANDLE timer = self->_timer;
if (timer == nullptr) {
timer = CreateWaitableTimerExW(nullptr, nullptr, CREATE_WAITABLE_TIMER_MANUAL_RESET | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
self->_timer = timer;
}
LARGE_INTEGER ft;
ft.QuadPart = seconds * -10000000LL;
SetWaitableTimer(timer, &ft, 0, nullptr, nullptr, 0);
WaitForSingleObject(timer, INFINITE);
}
/**
* Returns the number of context switches that occurred on the current thread.
* The first number is the total number of context switches reported by the OS,

View File

@ -48,7 +48,7 @@ public:
INLINE static bool is_threading_supported();
INLINE static bool is_true_threads();
INLINE static bool is_simple_threads();
INLINE static void sleep(double seconds);
static void sleep(double seconds);
INLINE static void yield();
INLINE static void consider_yield();
@ -72,6 +72,7 @@ private:
bool _joinable;
Status _status;
HANDLE _profiling;
HANDLE _timer = nullptr;
};
#include "threadWin32Impl.I"