29
29
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x2
30
30
#endif
31
31
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
-
90
32
Uint64 SDL_GetPerformanceCounter (void )
91
33
{
92
34
LARGE_INTEGER counter ;
@@ -103,31 +45,35 @@ Uint64 SDL_GetPerformanceFrequency(void)
103
45
return (Uint64 )frequency .QuadPart ;
104
46
}
105
47
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 )
107
51
{
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;
114
61
}
115
- return ;
116
- }
117
62
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
+ }
121
66
}
122
- const DWORD delay = (DWORD )SDL_NS_TO_MS (ns );
123
67
124
- HANDLE event = SDL_GetWaitableEvent ();
125
- if (event ) {
126
- WaitForSingleObjectEx (event , delay , FALSE);
127
- return ;
128
- }
68
+ pNtDelayExecution (Alertable , DelayInterval );
69
+ }
129
70
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 );
131
77
}
132
78
133
79
#endif // SDL_TIMER_WINDOWS
0 commit comments