16 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
21 #elif defined(_WIN32) || defined(_WIN64)
27 #define STATUS_SUCCESS 0x00000000
35 #if defined(_WIN32) || defined(_WIN64)
37 uint64_t SetMinimumTimerResolution()
39 static NTSTATUS(__stdcall *NtQueryTimerResolution)(OUT PULONG MinimumResolution, OUT PULONG MaximumResolution, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(PULONG, PULONG, PULONG))GetProcAddress(GetModuleHandle(
"ntdll.dll"),
"NtQueryTimerResolution");
40 static NTSTATUS(__stdcall *NtSetTimerResolution)(IN ULONG RequestedResolution, IN BOOLEAN Set, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(ULONG, BOOLEAN, PULONG))GetProcAddress(GetModuleHandle(
"ntdll.dll"),
"NtSetTimerResolution");
42 if ((NtQueryTimerResolution ==
nullptr) || (NtSetTimerResolution ==
nullptr))
45 ULONG MinimumResolution, MaximumResolution, ActualResolution;
46 NTSTATUS ns = NtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution);
47 if (ns == STATUS_SUCCESS)
49 ns = NtSetTimerResolution(std::min(MinimumResolution, MaximumResolution), TRUE, &ActualResolution);
50 if (ns == STATUS_SUCCESS)
51 return (ActualResolution * 100);
62 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
63 return (uint64_t)pthread_self();
64 #elif defined(_WIN32) || defined(_WIN64)
65 return GetCurrentThreadId();
67 #error Unsupported platform
73 #if defined(__APPLE__) || defined(__CYGWIN__)
75 #elif defined(unix) || defined(__unix) || defined(__unix__)
76 int affinity = sched_getcpu();
77 return (affinity < 0) ? 0 : affinity;
78 #elif defined(_WIN32) || defined(_WIN64)
79 return GetCurrentProcessorNumber();
89 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
90 struct timespec req, rem;
91 req.tv_sec = timespan.seconds();
92 req.tv_nsec = timespan.nanoseconds() % 1000000000;
95 while (nanosleep(&req, &rem) != 0)
102 #elif defined(_WIN32) || defined(_WIN64)
103 static NTSTATUS(__stdcall *NtDelayExecution)(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval) = (NTSTATUS(__stdcall*)(BOOLEAN, PLARGE_INTEGER))GetProcAddress(GetModuleHandle(
"ntdll.dll"),
"NtDelayExecution");
106 static int64_t resolution = Internals::SetMinimumTimerResolution();
108 int64_t sleep = timespan.nanoseconds();
109 int64_t yield = timespan.nanoseconds() % resolution;
127 if (NtDelayExecution !=
nullptr)
130 LARGE_INTEGER interval;
131 interval.QuadPart = -sleep / 100;
132 NtDelayExecution(FALSE, &interval);
137 Sleep(sleep / 1000000);
145 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
147 #elif defined(_WIN32) || defined(_WIN64)
154 #if defined(__APPLE__) || defined(__CYGWIN__)
155 return std::bitset<64>(0xFFFFFFFFFFFFFFFFull >> (64 -
CPU::Affinity()));
156 #elif defined(unix) || defined(__unix) || defined(__unix__)
159 int result = pthread_getaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
162 std::bitset<64> affinity;
163 for (
int i = 0; i < std::min(CPU_SETSIZE, 64); ++i)
164 if (CPU_ISSET(i, &cpuset))
167 #elif defined(_WIN32) || defined(_WIN64)
168 typedef LONG KPRIORITY;
170 typedef struct _NT_CLIENT_ID
172 HANDLE UniqueProcess;
176 typedef struct _THREAD_BASIC_INFORMATION
180 NT_CLIENT_ID ClientId;
181 ULONG_PTR AffinityMask;
184 } THREAD_BASIC_INFORMATION;
186 static NTSTATUS(__stdcall *NtQueryInformationThread)(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength) = (NTSTATUS(__stdcall*)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(GetModuleHandle(
"ntdll.dll"),
"NtQueryInformationThread");
188 if (NtQueryInformationThread !=
nullptr)
190 THREAD_BASIC_INFORMATION tbi;
191 ZeroMemory(&tbi,
sizeof(tbi));
192 NTSTATUS ns = NtQueryInformationThread(GetCurrentThread(), (THREADINFOCLASS)0, &tbi,
sizeof(tbi),
nullptr);
193 if (ns == STATUS_SUCCESS)
194 return std::bitset<64>(tbi.AffinityMask);
199 return std::bitset<64>(0xFFFFFFFFFFFFFFFFull >> (64 -
CPU::Affinity()));
205 #if defined(__APPLE__) || defined(__CYGWIN__)
206 return std::bitset<64>(0xFFFFFFFFFFFFFFFFull >> (64 -
CPU::Affinity()));
207 #elif defined(unix) || defined(__unix) || defined(__unix__)
210 int result = pthread_getaffinity_np(thread.native_handle(),
sizeof(cpu_set_t), &cpuset);
213 std::bitset<64> affinity;
214 for (
int i = 0; i < std::min(CPU_SETSIZE, 64); ++i)
215 if (CPU_ISSET(i, &cpuset))
218 #elif defined(_WIN32) || defined(_WIN64)
219 typedef LONG KPRIORITY;
221 typedef struct _NT_CLIENT_ID
223 HANDLE UniqueProcess;
227 typedef struct _THREAD_BASIC_INFORMATION
231 NT_CLIENT_ID ClientId;
232 ULONG_PTR AffinityMask;
235 } THREAD_BASIC_INFORMATION;
237 static NTSTATUS(__stdcall *NtQueryInformationThread)(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength) = (NTSTATUS(__stdcall*)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(GetModuleHandle(
"ntdll.dll"),
"NtQueryInformationThread");
239 if (NtQueryInformationThread !=
nullptr)
241 THREAD_BASIC_INFORMATION tbi;
242 ZeroMemory(&tbi,
sizeof(tbi));
243 NTSTATUS ns = NtQueryInformationThread((HANDLE)thread.native_handle(), (THREADINFOCLASS)0, &tbi,
sizeof(tbi),
nullptr);
244 if (ns == STATUS_SUCCESS)
245 return std::bitset<64>(tbi.AffinityMask);
250 return std::bitset<64>(0xFFFFFFFFFFFFFFFFull >> (64 -
CPU::Affinity()));
256 #if defined(__APPLE__)
258 #elif defined(__CYGWIN__)
260 #elif defined(unix) || defined(__unix) || defined(__unix__)
263 for (
int i = 0; i < std::min(CPU_SETSIZE, 64); ++i)
266 int result = pthread_setaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
269 #elif defined(_WIN32) || defined(_WIN64)
270 DWORD_PTR dwThreadAffinityMask = (DWORD_PTR)affinity.to_ullong();
271 if (!SetThreadAffinityMask(GetCurrentThread(), dwThreadAffinityMask))
278 #if defined(__APPLE__)
280 #elif defined(__CYGWIN__)
282 #elif defined(unix) || defined(__unix) || defined(__unix__)
285 for (
int i = 0; i < std::min(CPU_SETSIZE, 64); ++i)
288 int result = pthread_setaffinity_np(thread.native_handle(),
sizeof(cpu_set_t), &cpuset);
291 #elif defined(_WIN32) || defined(_WIN64)
292 DWORD_PTR dwThreadAffinityMask = (DWORD_PTR)affinity.to_ullong();
293 if (!SetThreadAffinityMask((HANDLE)thread.native_handle(), dwThreadAffinityMask))
300 #if defined(__CYGWIN__)
302 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
304 struct sched_param sched;
305 int result = pthread_getschedparam(pthread_self(), &policy, &sched);
308 if ((policy == SCHED_FIFO) || (policy == SCHED_RR))
310 if (sched.sched_priority < 15)
312 else if (sched.sched_priority < 30)
314 else if (sched.sched_priority < 50)
316 else if (sched.sched_priority < 70)
318 else if (sched.sched_priority < 85)
320 else if (sched.sched_priority < 99)
327 #elif defined(_WIN32) || defined(_WIN64)
328 int priority = GetThreadPriority(GetCurrentThread());
329 if (priority == THREAD_PRIORITY_ERROR_RETURN)
331 if (priority < THREAD_PRIORITY_LOWEST)
333 else if (priority < THREAD_PRIORITY_BELOW_NORMAL)
335 else if (priority < THREAD_PRIORITY_NORMAL)
337 else if (priority < THREAD_PRIORITY_ABOVE_NORMAL)
339 else if (priority < THREAD_PRIORITY_HIGHEST)
341 else if (priority < THREAD_PRIORITY_TIME_CRITICAL)
350 #if defined(__CYGWIN__)
352 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
354 struct sched_param sched;
355 int result = pthread_getschedparam(thread.native_handle(), &policy, &sched);
358 if ((policy == SCHED_FIFO) || (policy == SCHED_RR))
360 if (sched.sched_priority < 15)
362 else if (sched.sched_priority < 30)
364 else if (sched.sched_priority < 50)
366 else if (sched.sched_priority < 70)
368 else if (sched.sched_priority < 85)
370 else if (sched.sched_priority < 99)
377 #elif defined(_WIN32) || defined(_WIN64)
378 int priority = GetThreadPriority((HANDLE)thread.native_handle());
379 if (priority == THREAD_PRIORITY_ERROR_RETURN)
381 if (priority < THREAD_PRIORITY_LOWEST)
383 else if (priority < THREAD_PRIORITY_BELOW_NORMAL)
385 else if (priority < THREAD_PRIORITY_NORMAL)
387 else if (priority < THREAD_PRIORITY_ABOVE_NORMAL)
389 else if (priority < THREAD_PRIORITY_HIGHEST)
391 else if (priority < THREAD_PRIORITY_TIME_CRITICAL)
400 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
401 int policy = SCHED_RR;
402 struct sched_param sched;
403 sched.sched_priority = 50;
407 sched.sched_priority = 1;
410 sched.sched_priority = 15;
413 sched.sched_priority = 30;
416 sched.sched_priority = 50;
419 sched.sched_priority = 70;
422 sched.sched_priority = 85;
425 sched.sched_priority = 99;
429 int result = pthread_setschedparam(pthread_self(), policy, &sched);
432 #elif defined(_WIN32) || defined(_WIN64)
433 int nPriority = THREAD_PRIORITY_NORMAL;
437 nPriority = THREAD_PRIORITY_IDLE;
440 nPriority = THREAD_PRIORITY_LOWEST;
443 nPriority = THREAD_PRIORITY_BELOW_NORMAL;
446 nPriority = THREAD_PRIORITY_NORMAL;
449 nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
452 nPriority = THREAD_PRIORITY_HIGHEST;
455 nPriority = THREAD_PRIORITY_TIME_CRITICAL;
459 if (!SetThreadPriority(GetCurrentThread(), nPriority))
466 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
467 int policy = SCHED_RR;
468 struct sched_param sched;
469 sched.sched_priority = 50;
473 sched.sched_priority = 1;
476 sched.sched_priority = 15;
479 sched.sched_priority = 30;
482 sched.sched_priority = 50;
485 sched.sched_priority = 70;
488 sched.sched_priority = 85;
491 sched.sched_priority = 99;
495 int result = pthread_setschedparam(thread.native_handle(), policy, &sched);
498 #elif defined(_WIN32) || defined(_WIN64)
499 int nPriority = THREAD_PRIORITY_NORMAL;
503 nPriority = THREAD_PRIORITY_IDLE;
506 nPriority = THREAD_PRIORITY_LOWEST;
509 nPriority = THREAD_PRIORITY_BELOW_NORMAL;
512 nPriority = THREAD_PRIORITY_NORMAL;
515 nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
518 nPriority = THREAD_PRIORITY_HIGHEST;
521 nPriority = THREAD_PRIORITY_TIME_CRITICAL;
525 if (!SetThreadPriority((HANDLE)thread.native_handle(), nPriority))
static int Affinity()
CPU affinity count.
static ThreadPriority GetPriority()
Get the current thread priority.
static uint64_t CurrentThreadId() noexcept
Get the current thread Id.
static void SleepFor(const Timespan ×pan) noexcept
Sleep the current thread for the given timespan.
static void SetPriority(ThreadPriority priority)
Set the current thread priority.
static std::bitset< 64 > GetAffinity()
Get the current thread CPU affinity bitset.
static void Yield() noexcept
Yield to other threads.
static uint32_t CurrentThreadAffinity() noexcept
Get the current thread CPU affinity.
static void SetAffinity(const std::bitset< 64 > &affinity)
Set the current thread CPU affinity bitset.
static uint64_t nano()
Get the high resolution timestamp.
CPU management definition.
#define throwex
Throw extended exception macro.
C++ Common project definitions.
ThreadPriority
Thread priorities.
@ NORMAL
Normal thread priority.
@ LOW
Low thread priority.
@ REALTIME
Realtime thread priority.
@ LOWEST
Lowest thread priority.
@ IDLE
Idle thread priority.
@ HIGH
High thread priority.
@ HIGHEST
Highest thread priority.