From e92e4d8b505b4707c2692b1ea3b2a13370a4d2d3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 23 May 2023 11:32:40 -0700 Subject: [PATCH] Save waitable timers in thread local storage instead of continuously allocating and freeing them Fixes https://github.com/libsdl-org/SDL/issues/6597 --- src/timer/windows/SDL_systimer.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/timer/windows/SDL_systimer.c b/src/timer/windows/SDL_systimer.c index 15c872e68..8dd6057ea 100644 --- a/src/timer/windows/SDL_systimer.c +++ b/src/timer/windows/SDL_systimer.c @@ -25,6 +25,31 @@ #include "../../core/windows/SDL_windows.h" +#ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +static void SDL_CleanupWaitableTimer(void *timer) +{ + CloseHandle(timer); +} + +HANDLE SDL_GetWaitableTimer() +{ + static SDL_TLSID TLS_timer_handle; + HANDLE timer; + + if (!TLS_timer_handle) { + TLS_timer_handle = SDL_TLSCreate(); + } + timer = SDL_TLSGet(TLS_timer_handle); + if (!timer) { + timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); + if (timer) { + SDL_TLSSet(TLS_timer_handle, timer, SDL_CleanupWaitableTimer); + } + } + return timer; +} +#endif /* CREATE_WAITABLE_TIMER_HIGH_RESOLUTION */ + Uint64 SDL_GetPerformanceCounter(void) { LARGE_INTEGER counter; @@ -58,14 +83,13 @@ void SDL_DelayNS(Uint64 ns) * apps and libraries. */ #ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION - HANDLE timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); + HANDLE timer = SDL_GetWaitableTimer(); if (timer) { LARGE_INTEGER due_time; due_time.QuadPart = -((LONGLONG)ns / 100); if (SetWaitableTimerEx(timer, &due_time, 0, NULL, NULL, NULL, 0)) { WaitForSingleObject(timer, INFINITE); } - CloseHandle(timer); return; } #endif