engine: platform: win32: implement nanosleep using waitable timers with high precision
This commit is contained in:
parent
052ea6a8bd
commit
af6b434b71
2 changed files with 44 additions and 27 deletions
|
@ -70,8 +70,9 @@ void Android_Shutdown( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XASH_WIN32
|
#if XASH_WIN32
|
||||||
void Win32_Init( void );
|
void Win32_Init( qboolean con_showalways );
|
||||||
void Win32_Shutdown( void );
|
void Win32_Shutdown( void );
|
||||||
|
qboolean Win32_NanoSleep( int nsec );
|
||||||
void Wcon_CreateConsole( qboolean con_showalways );
|
void Wcon_CreateConsole( qboolean con_showalways );
|
||||||
void Wcon_DestroyConsole( void );
|
void Wcon_DestroyConsole( void );
|
||||||
void Wcon_InitConsoleCommands( void );
|
void Wcon_InitConsoleCommands( void );
|
||||||
|
@ -126,8 +127,7 @@ static inline void Platform_Init( qboolean con_showalways, const char *basedir )
|
||||||
#elif XASH_DOS
|
#elif XASH_DOS
|
||||||
DOS_Init( );
|
DOS_Init( );
|
||||||
#elif XASH_WIN32
|
#elif XASH_WIN32
|
||||||
Win32_Init( );
|
Win32_Init( con_showalways );
|
||||||
Wcon_CreateConsole( con_showalways );
|
|
||||||
#elif XASH_LINUX
|
#elif XASH_LINUX
|
||||||
Linux_Init( );
|
Linux_Init( );
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,7 +142,6 @@ static inline void Platform_Shutdown( void )
|
||||||
#elif XASH_DOS
|
#elif XASH_DOS
|
||||||
DOS_Shutdown( );
|
DOS_Shutdown( );
|
||||||
#elif XASH_WIN32
|
#elif XASH_WIN32
|
||||||
Wcon_DestroyConsole( );
|
|
||||||
Win32_Shutdown( );
|
Win32_Shutdown( );
|
||||||
#elif XASH_LINUX
|
#elif XASH_LINUX
|
||||||
Linux_Shutdown( );
|
Linux_Shutdown( );
|
||||||
|
@ -193,23 +192,9 @@ static inline qboolean Platform_NanoSleep( int nsec )
|
||||||
};
|
};
|
||||||
return nanosleep( &ts, NULL ) == 0;
|
return nanosleep( &ts, NULL ) == 0;
|
||||||
#elif XASH_WIN32
|
#elif XASH_WIN32
|
||||||
extern HANDLE g_waitable_timer;
|
return Win32_NanoSleep( nsec );
|
||||||
const LARGE_INTEGER ts = { -nsec };
|
#else
|
||||||
|
return false;
|
||||||
if( !g_waitable_timer )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if( !SetWaitableTimer( g_waitable_timer, &ts, 0, NULL, NULL, FALSE ))
|
|
||||||
{
|
|
||||||
CloseHandle( g_waitable_timer );
|
|
||||||
g_waitable_timer = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( WaitForSingleObject( g_waitable_timer, 1000 ) != WAIT_OBJECT_0 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,31 +38,63 @@ double Platform_DoubleTime( void )
|
||||||
}
|
}
|
||||||
#endif // XASH_TIMER == TIMER_WIN32
|
#endif // XASH_TIMER == TIMER_WIN32
|
||||||
|
|
||||||
void Win32_Init( void )
|
void Win32_Init( qboolean con_showalways )
|
||||||
{
|
{
|
||||||
HMODULE hModule = LoadLibrary( "kernel32.dll" );
|
HMODULE hModule = LoadLibrary( "kernel32.dll" );
|
||||||
|
|
||||||
if( hModule )
|
if( hModule )
|
||||||
{
|
{
|
||||||
HANDLE ( __stdcall *pfnCreateWaitableTimerExW)( LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess );
|
HANDLE ( __stdcall *pfnCreateWaitableTimerExW)( LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess );
|
||||||
|
|
||||||
if(( pfnCreateWaitableTimerExW = GetProcAddress( hModule, "CreateWaitableTimerExW" )))
|
if(( pfnCreateWaitableTimerExW = (void *)GetProcAddress( hModule, "CreateWaitableTimerExW" )))
|
||||||
{
|
{
|
||||||
// CREATE_WAITABLE_TIMER_MANUAL_RESET | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
|
g_waitable_timer = pfnCreateWaitableTimerExW(
|
||||||
g_waitable_timer = pfnCreateWaitableTimerExW( NULL, NULL, 0x1 | 0x2, 0 );
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0x1 /* CREATE_WAITABLE_TIMER_MANUAL_RESET */ | 0x2 /* CREATE_WAITABLE_TIMER_HIGH_RESOLUTION */,
|
||||||
|
0x0002 /* TIMER_MODIFY_STATE */ | SYNCHRONIZE | DELETE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeLibrary( "kernel32.dll" );
|
FreeLibrary( hModule );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // FIXME: creates object but doesn't wait for specific time for me on Windows 10, with the code above commented
|
||||||
if( !g_waitable_timer )
|
if( !g_waitable_timer )
|
||||||
g_waitable_timer = CreateWaitableTimer( NULL, TRUE, NULL );
|
g_waitable_timer = CreateWaitableTimer( NULL, TRUE, NULL );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Wcon_CreateConsole( con_showalways );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win32_Shutdown( void )
|
void Win32_Shutdown( void )
|
||||||
{
|
{
|
||||||
|
Wcon_DestroyConsole( );
|
||||||
|
|
||||||
if( g_waitable_timer )
|
if( g_waitable_timer )
|
||||||
|
{
|
||||||
CloseHandle( g_waitable_timer );
|
CloseHandle( g_waitable_timer );
|
||||||
|
g_waitable_timer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean Win32_NanoSleep( int nsec )
|
||||||
|
{
|
||||||
|
const LARGE_INTEGER ts = { -nsec };
|
||||||
|
|
||||||
|
if( !g_waitable_timer )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !SetWaitableTimer( g_waitable_timer, &ts, 0, NULL, NULL, FALSE ))
|
||||||
|
{
|
||||||
|
CloseHandle( g_waitable_timer );
|
||||||
|
g_waitable_timer = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( WaitForSingleObject( g_waitable_timer, Q_max( 1, nsec / 1000000 )) != WAIT_OBJECT_0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean Platform_DebuggerPresent( void )
|
qboolean Platform_DebuggerPresent( void )
|
||||||
|
|
Loading…
Add table
Reference in a new issue