Created
January 7, 2025 10:58
-
-
Save MisterDA/0fbafad732d74187147111a90f618fcc to your computer and use it in GitHub Desktop.
Windows high-resolution timer test
This file contains hidden or 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
#include <windows.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define NSEC_PER_SEC UINT64_C(1000000000) | |
#define NSEC_PER_MSEC UINT64_C(1000000) | |
struct caml_state { | |
HANDLE timer; | |
}; | |
static caml_state Caml_state; | |
#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION | |
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 | |
#endif | |
static HANDLE caml_win32_create_timer(void) | |
{ | |
return CreateWaitableTimerEx(NULL, NULL, | |
CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, | |
SYNCHRONIZE | TIMER_QUERY_STATE | |
| TIMER_MODIFY_STATE); | |
} | |
static void caml_win32_destroy_timer(HANDLE timer) | |
{ | |
if (timer != INVALID_HANDLE_VALUE) | |
CloseHandle(timer); | |
} | |
/* FIXME: error handling? */ | |
static void caml_win32_nanosleep(uint64_t sec, uint64_t nsec) | |
{ | |
HANDLE timer = Caml_state->timer; | |
DWORD timeout_msec; | |
/* If the high-resolution timer is available, use it. Otherwise, | |
* fall-back to the low-resolution timer, which doesn't need a | |
* handle. */ | |
if (timer != INVALID_HANDLE_VALUE) { | |
LARGE_INTEGER dt; | |
/* relative sleep (negative), 100ns units */ | |
dt.QuadPart = -(int64_t)(sec * (NSEC_PER_SEC / 100) + nsec / 100); | |
SetWaitableTimer(timer, &dt, 0, NULL, NULL, FALSE); | |
timeout_msec = INFINITE; | |
} else { | |
uint64_t msec = sec * MSEC_PER_SEC + nsec / NSEC_PER_MSEC; | |
timeout_msec = msec < INFINITE ? (DWORD) msec : INFINITE - 1; | |
} | |
WaitForSingleObject(timer, timeout_msec); | |
} | |
int main(int argc, char *argv[]) { | |
if (argc != 2) exit(EXIT_FAILURE); | |
double timeout = strtof(argv[1], NULL); | |
double sec, nsec; | |
nsec = modf(timeout, &sec) * NSEC_PER_SEC; | |
Caml_state->timer = caml_win32_create_timer(); | |
printf("sleeping for %f sec %f nsec...\n", sec, nsec); | |
caml_win32_nanosleep(sec, nsec); | |
caml_win32_destroy_timer(Caml_state->timer); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment