Skip to content

Commit 6bc8dfe

Browse files
committed
use NtDelayExecution for SDL_SYS_DelayNS
1 parent 98bed62 commit 6bc8dfe

File tree

1 file changed

+23
-77
lines changed

1 file changed

+23
-77
lines changed

src/timer/windows/SDL_systimer.c

Lines changed: 23 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -29,64 +29,6 @@
2929
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x2
3030
#endif
3131

32-
typedef HANDLE (WINAPI *CreateWaitableTimerExW_t)(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess);
33-
static CreateWaitableTimerExW_t pCreateWaitableTimerExW;
34-
35-
typedef BOOL (WINAPI *SetWaitableTimerEx_t)(HANDLE hTimer, const LARGE_INTEGER *lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay);
36-
static SetWaitableTimerEx_t pSetWaitableTimerEx;
37-
38-
static void SDL_CleanupWaitableHandle(void *handle)
39-
{
40-
CloseHandle(handle);
41-
}
42-
43-
static HANDLE SDL_GetWaitableTimer(void)
44-
{
45-
static SDL_TLSID TLS_timer_handle;
46-
HANDLE timer;
47-
48-
if (!pCreateWaitableTimerExW || !pSetWaitableTimerEx) {
49-
static bool initialized;
50-
51-
if (!initialized) {
52-
HMODULE module = GetModuleHandle(TEXT("kernel32.dll"));
53-
if (module) {
54-
pCreateWaitableTimerExW = (CreateWaitableTimerExW_t)GetProcAddress(module, "CreateWaitableTimerExW");
55-
pSetWaitableTimerEx = (SetWaitableTimerEx_t)GetProcAddress(module, "SetWaitableTimerEx");
56-
}
57-
initialized = true;
58-
}
59-
60-
if (!pCreateWaitableTimerExW || !pSetWaitableTimerEx) {
61-
return NULL;
62-
}
63-
}
64-
65-
timer = SDL_GetTLS(&TLS_timer_handle);
66-
if (!timer) {
67-
timer = pCreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
68-
if (timer) {
69-
SDL_SetTLS(&TLS_timer_handle, timer, SDL_CleanupWaitableHandle);
70-
}
71-
}
72-
return timer;
73-
}
74-
75-
static HANDLE SDL_GetWaitableEvent(void)
76-
{
77-
static SDL_TLSID TLS_event_handle;
78-
HANDLE event;
79-
80-
event = SDL_GetTLS(&TLS_event_handle);
81-
if (!event) {
82-
event = CreateEvent(NULL, FALSE, FALSE, NULL);
83-
if (event) {
84-
SDL_SetTLS(&TLS_event_handle, event, SDL_CleanupWaitableHandle);
85-
}
86-
}
87-
return event;
88-
}
89-
9032
Uint64 SDL_GetPerformanceCounter(void)
9133
{
9234
LARGE_INTEGER counter;
@@ -103,31 +45,35 @@ Uint64 SDL_GetPerformanceFrequency(void)
10345
return (Uint64)frequency.QuadPart;
10446
}
10547

106-
void SDL_SYS_DelayNS(Uint64 ns)
48+
typedef DWORD (NTAPI *NtDelayExecution_t)(BOOLEAN Alertable, PLARGE_INTEGER DelayInterval);
49+
static NtDelayExecution_t pNtDelayExecution;
50+
static void SDL_NtDelayExecution(BOOLEAN Alertable, PLARGE_INTEGER DelayInterval)
10751
{
108-
HANDLE timer = SDL_GetWaitableTimer();
109-
if (timer) {
110-
LARGE_INTEGER due_time;
111-
due_time.QuadPart = -((LONGLONG)ns / 100);
112-
if (pSetWaitableTimerEx(timer, &due_time, 0, NULL, NULL, NULL, 0)) {
113-
WaitForSingleObject(timer, INFINITE);
52+
if (!pNtDelayExecution) {
53+
static bool initialized;
54+
55+
if (!initialized) {
56+
HMODULE module = GetModuleHandle(TEXT("ntdll.dll"));
57+
if (module) {
58+
pNtDelayExecution = (NtDelayExecution_t)GetProcAddress(module, "NtDelayExecution");
59+
}
60+
initialized = true;
11461
}
115-
return;
116-
}
11762

118-
const Uint64 max_delay = 0xffffffffLL * SDL_NS_PER_MS;
119-
if (ns > max_delay) {
120-
ns = max_delay;
63+
if (!pNtDelayExecution) {
64+
return;
65+
}
12166
}
122-
const DWORD delay = (DWORD)SDL_NS_TO_MS(ns);
12367

124-
HANDLE event = SDL_GetWaitableEvent();
125-
if (event) {
126-
WaitForSingleObjectEx(event, delay, FALSE);
127-
return;
128-
}
68+
pNtDelayExecution(Alertable, DelayInterval);
69+
}
12970

130-
Sleep(delay);
71+
void SDL_SYS_DelayNS(Uint64 ns)
72+
{
73+
Sint64 tick = ns;
74+
tick /= 100;
75+
tick *= -1;
76+
SDL_NtDelayExecution(0, (PLARGE_INTEGER)&tick);
13177
}
13278

13379
#endif // SDL_TIMER_WINDOWS

0 commit comments

Comments
 (0)