mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-07 12:50:38 +08:00
engine: platform: introduce for Platform_NanoSleep, to be used for better sleeping in between frames for lowering CPU usage
This commit is contained in:
@@ -698,17 +698,17 @@ static qboolean Host_Autosleep( double dt, double scale )
|
||||
static double timewindow; // allocate a time window for sleeps
|
||||
static int counter; // for debug
|
||||
static double realsleeptime;
|
||||
const double sleeptime = sleep * 0.001;
|
||||
const double sleeptime = sleep * 0.000001;
|
||||
|
||||
if( dt < targetframetime * scale )
|
||||
{
|
||||
// if we have allocated time window, try to sleep
|
||||
if( timewindow > realsleeptime )
|
||||
{
|
||||
// Platform_Sleep isn't guaranteed to sleep an exact amount of milliseconds
|
||||
// Platform_Sleep isn't guaranteed to sleep an exact amount of microseconds
|
||||
// so we measure the real sleep time and use it to decrease the window
|
||||
double t1 = Sys_DoubleTime(), t2;
|
||||
Platform_Sleep( sleep ); // in msec!
|
||||
Platform_NanoSleep( sleep * 1000 ); // in usec!
|
||||
t2 = Sys_DoubleTime();
|
||||
realsleeptime = t2 - t1;
|
||||
|
||||
|
||||
@@ -1512,7 +1512,7 @@ static int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, size_t
|
||||
total_sent += size;
|
||||
len -= size;
|
||||
packet_number++;
|
||||
Platform_Sleep( 1 );
|
||||
Platform_NanoSleep( 100 * 1000 );
|
||||
}
|
||||
|
||||
return total_sent;
|
||||
|
||||
@@ -70,6 +70,8 @@ void Android_Shutdown( void );
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
void Win32_Init( void );
|
||||
void Win32_Shutdown( void );
|
||||
void Wcon_CreateConsole( qboolean con_showalways );
|
||||
void Wcon_DestroyConsole( void );
|
||||
void Wcon_InitConsoleCommands( void );
|
||||
@@ -124,6 +126,7 @@ static inline void Platform_Init( qboolean con_showalways, const char *basedir )
|
||||
#elif XASH_DOS
|
||||
DOS_Init( );
|
||||
#elif XASH_WIN32
|
||||
Win32_Init( );
|
||||
Wcon_CreateConsole( con_showalways );
|
||||
#elif XASH_LINUX
|
||||
Linux_Init( );
|
||||
@@ -140,6 +143,7 @@ static inline void Platform_Shutdown( void )
|
||||
DOS_Shutdown( );
|
||||
#elif XASH_WIN32
|
||||
Wcon_DestroyConsole( );
|
||||
Win32_Shutdown( );
|
||||
#elif XASH_LINUX
|
||||
Linux_Shutdown( );
|
||||
#endif
|
||||
@@ -178,6 +182,37 @@ static inline void Platform_Sleep( int msec )
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline qboolean Platform_NanoSleep( int nsec )
|
||||
{
|
||||
// SDL2 doesn't have nanosleep, so use low-level functions here
|
||||
// When this code will be ported to SDL3, use SDL_DelayNS
|
||||
#if XASH_POSIX
|
||||
struct timespec ts = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = nsec, // just don't put large numbers here
|
||||
};
|
||||
return nanosleep( &ts, NULL ) == 0;
|
||||
#elif XASH_WIN32
|
||||
extern HANDLE g_waitable_timer;
|
||||
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, 1000 ) != WAIT_OBJECT_0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_WIN32 || XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX || XASH_APPLE
|
||||
void Sys_SetupCrashHandler( const char *argv0 );
|
||||
void Sys_RestoreCrashHandler( void );
|
||||
|
||||
@@ -18,6 +18,8 @@ GNU General Public License for more details.
|
||||
#include "server.h"
|
||||
#include <shellapi.h>
|
||||
|
||||
HANDLE g_waitable_timer;
|
||||
|
||||
#if XASH_TIMER == TIMER_WIN32
|
||||
double Platform_DoubleTime( void )
|
||||
{
|
||||
@@ -36,6 +38,33 @@ double Platform_DoubleTime( void )
|
||||
}
|
||||
#endif // XASH_TIMER == TIMER_WIN32
|
||||
|
||||
void Win32_Init( void )
|
||||
{
|
||||
HMODULE hModule = LoadLibrary( "kernel32.dll" );
|
||||
|
||||
if( hModule )
|
||||
{
|
||||
HANDLE ( __stdcall *pfnCreateWaitableTimerExW)( LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess );
|
||||
|
||||
if(( pfnCreateWaitableTimerExW = GetProcAddress( hModule, "CreateWaitableTimerExW" )))
|
||||
{
|
||||
// CREATE_WAITABLE_TIMER_MANUAL_RESET | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
|
||||
g_waitable_timer = pfnCreateWaitableTimerExW( NULL, NULL, 0x1 | 0x2, 0 );
|
||||
}
|
||||
|
||||
FreeLibrary( "kernel32.dll" );
|
||||
}
|
||||
|
||||
if( !g_waitable_timer )
|
||||
g_waitable_timer = CreateWaitableTimer( NULL, TRUE, NULL );
|
||||
}
|
||||
|
||||
void Win32_Shutdown( void )
|
||||
{
|
||||
if( g_waitable_timer )
|
||||
CloseHandle( g_waitable_timer );
|
||||
}
|
||||
|
||||
qboolean Platform_DebuggerPresent( void )
|
||||
{
|
||||
return IsDebuggerPresent();
|
||||
|
||||
Reference in New Issue
Block a user