Created
February 25, 2016 20:43
-
-
Save GoaLitiuM/aff9fbfa4294fa6c1680 to your computer and use it in GitHub Desktop.
usleep() for Windows (C/C++) + set timer resolution to lowest possible supported by system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <stdio.h> | |
#include "usleep.h" | |
int main() | |
{ | |
// not actually needed when calling usleep | |
setHighestTimerResolution(1); | |
LARGE_INTEGER qpc_begin, qpc_end, qpc_freq; | |
QueryPerformanceCounter(&qpc_begin); | |
QueryPerformanceFrequency(&qpc_freq); | |
// usleep(1) sleeps at lowest possible amount of time | |
int times = 1000; | |
for (int i=0; i<times; i++) | |
usleep(1); | |
QueryPerformanceCounter(&qpc_end); | |
double delay = (qpc_end.QuadPart - qpc_begin.QuadPart) / (double)qpc_freq.QuadPart; | |
delay *= 1000.0 / times; | |
printf_s("Average sleep time of usleep(1): %lfms\n", delay); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <limits.h> | |
#include <winnt.h> | |
#include "usleep.h" | |
unsigned long currentResolution = 0; | |
unsigned long setHighestTimerResolution(unsigned long timer_res_us) | |
{ | |
unsigned long timer_current_res = ULONG_MAX; | |
const HINSTANCE ntdll = LoadLibrary("NTDLL.dll"); | |
if (ntdll != NULL) | |
{ | |
typedef long(NTAPI* pNtSetTimerResolution)(unsigned long RequestedResolution, BOOLEAN Set, unsigned long* ActualResolution); | |
pNtSetTimerResolution NtSetTimerResolution = (pNtSetTimerResolution) GetProcAddress(ntdll, "NtSetTimerResolution"); | |
if (NtSetTimerResolution != NULL) | |
{ | |
// bounds are validated and set to the highest allowed resolution | |
NtSetTimerResolution(timer_res_us, TRUE, &timer_current_res); | |
} | |
// we can decrement the internal reference count by one | |
// and NTDLL.DLL still remains loaded in the process | |
FreeLibrary(ntdll); | |
} | |
return timer_current_res; | |
} | |
void usleep(__int64 usec) | |
{ | |
HANDLE timer; | |
LARGE_INTEGER period; | |
if (currentResolution == 0) | |
currentResolution = setHighestTimerResolution(1); | |
// negative values are for relative time | |
period.QuadPart = -(10*usec); | |
timer = CreateWaitableTimer(NULL, TRUE, NULL); | |
SetWaitableTimer(timer, &period, 0, NULL, NULL, 0); | |
WaitForSingleObject(timer, INFINITE); | |
CloseHandle(timer); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
// Sets resolution of timers used by Sleep() and SetWaitableTimer() to most accurate and lowest values possible supported by system. | |
// Same as timeBeginPeriod() but accepts microsecond precision for requested resolution. | |
unsigned long setHighestTimerResolution(unsigned long timer_res_us); | |
// Suspends the current thread in sleep for time period, in microseconds. | |
void usleep(__int64 usec); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment