Skip to content

Instantly share code, notes, and snippets.

@GoaLitiuM
Created February 25, 2016 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GoaLitiuM/aff9fbfa4294fa6c1680 to your computer and use it in GitHub Desktop.
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
#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;
}
#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);
}
#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