41 lines
1.0 KiB
C++
41 lines
1.0 KiB
C++
#ifndef CORE_LIBS_PRX_LIBC_INCLUDE_PRECISEWAIT_HPP
|
|
#define CORE_LIBS_PRX_LIBC_INCLUDE_PRECISEWAIT_HPP
|
|
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
inline constexpr unsigned long long kSubTickWaitUs = 2000;
|
|
|
|
inline void PreciseSleepUs(unsigned long long micros) {
|
|
if (micros == 0) {
|
|
return;
|
|
}
|
|
#ifdef _WIN32
|
|
struct Timer {
|
|
HANDLE handle = CreateWaitableTimerExW(nullptr, nullptr,
|
|
CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
|
|
~Timer() {
|
|
if (handle != nullptr) {
|
|
CloseHandle(handle);
|
|
}
|
|
}
|
|
};
|
|
thread_local Timer timer;
|
|
if (timer.handle != nullptr) {
|
|
LARGE_INTEGER due{};
|
|
due.QuadPart = -static_cast<LONGLONG>(micros * 10ULL);
|
|
if (SetWaitableTimerEx(timer.handle, &due, 0, nullptr, nullptr, nullptr, 0) != FALSE) {
|
|
WaitForSingleObject(timer.handle, INFINITE);
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
std::this_thread::sleep_for(std::chrono::microseconds(micros));
|
|
}
|
|
|
|
#endif
|