diff options
Diffstat (limited to 'external/vpc/tier0/platform_posix.cpp')
| -rw-r--r-- | external/vpc/tier0/platform_posix.cpp | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/external/vpc/tier0/platform_posix.cpp b/external/vpc/tier0/platform_posix.cpp new file mode 100644 index 0000000..90a8c76 --- /dev/null +++ b/external/vpc/tier0/platform_posix.cpp @@ -0,0 +1,426 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "pch_tier0.h" +#include "tier0/platform.h" +#include "tier0/memalloc.h" +#include "tier0/dbg.h" +#include "tier0/threadtools.h" + +#include <sys/time.h> +#include <unistd.h> + +#ifdef OSX +#include <sys/sysctl.h> +#include <mach/mach.h> +#include <mach/mach_time.h> +#endif + + +static bool g_bBenchmarkMode = false; +static double g_FakeBenchmarkTime = 0; +static double g_FakeBenchmarkTimeInc = 1.0 / 66.0; + + +bool Plat_IsInBenchmarkMode() +{ + return g_bBenchmarkMode; +} + +void Plat_SetBenchmarkMode( bool bBenchmark ) +{ + g_bBenchmarkMode = bBenchmark; +} + + + +#ifdef OSX + +static uint64 start_time = 0; +static mach_timebase_info_data_t sTimebaseInfo; +static double conversion = 0.0; + +void InitTime() +{ + start_time = mach_absolute_time(); + mach_timebase_info(&sTimebaseInfo); + conversion = 1e-9 * (double) sTimebaseInfo.numer / (double) sTimebaseInfo.denom; +} + +uint64 Plat_GetClockStart() +{ + if ( !start_time ) + { + InitTime(); + } + + return start_time * conversion; +} + +double Plat_FloatTime() +{ + if ( g_bBenchmarkMode ) + { + g_FakeBenchmarkTime += g_FakeBenchmarkTimeInc; + return g_FakeBenchmarkTime; + } + + if ( !start_time ) + { + InitTime(); + } + + uint64 now = mach_absolute_time(); + + return ( now - start_time ) * conversion; +} +#else + +static int secbase = 0; + +void InitTime( struct timeval &tp ) +{ + secbase = tp.tv_sec; +} + +uint64 Plat_GetClockStart() +{ + if ( !secbase ) + { + struct timeval tp; + gettimeofday( &tp, NULL ); + InitTime( tp ); + } + + return secbase; +} + + +double Plat_FloatTime() +{ + if ( g_bBenchmarkMode ) + { + g_FakeBenchmarkTime += g_FakeBenchmarkTimeInc; + return g_FakeBenchmarkTime; + } + + struct timeval tp; + + gettimeofday( &tp, NULL ); + + if ( !secbase ) + { + InitTime( tp ); + return ( tp.tv_usec / 1000000.0 ); + } + + return (( tp.tv_sec - secbase ) + tp.tv_usec / 1000000.0 ); +} +#endif + + +uint32 Plat_MSTime() +{ + if ( g_bBenchmarkMode ) + { + g_FakeBenchmarkTime += g_FakeBenchmarkTimeInc; + return (unsigned long)(g_FakeBenchmarkTime * 1000.0); + } + + struct timeval tp; + static int secbase = 0; + + gettimeofday( &tp, NULL ); + + if ( !secbase ) + { + secbase = tp.tv_sec; + return ( tp.tv_usec / 1000.0 ); + } + + return (unsigned long)(( tp.tv_sec - secbase )*1000.0 + tp.tv_usec / 1000.0 ); + +} + +// Wraps the thread-safe versions of asctime. buf must be at least 26 bytes +char *Plat_asctime( const struct tm *tm, char *buf, size_t bufsize ) +{ + return asctime_r( tm, buf ); +} + +// Wraps the thread-safe versions of ctime. buf must be at least 26 bytes +char *Plat_ctime( const time_t *timep, char *buf, size_t bufsize ) +{ + return ctime_r( timep, buf ); +} + +// Wraps the thread-safe versions of gmtime +struct tm *Plat_gmtime( const time_t *timep, struct tm *result ) +{ + return gmtime_r( timep, result ); +} + +time_t Plat_timegm( struct tm *timeptr ) +{ + return timegm( timeptr ); +} + +// Wraps the thread-safe versions of localtime +struct tm *Plat_localtime( const time_t *timep, struct tm *result ) +{ + return localtime_r( timep, result ); +} + +bool vtune( bool resume ) +{ +} + + +// -------------------------------------------------------------------------------------------------- // +// Memory stuff. +// -------------------------------------------------------------------------------------------------- // + +PLATFORM_INTERFACE void Plat_DefaultAllocErrorFn( unsigned long size ) +{ +} + +typedef void (*Plat_AllocErrorFn)( unsigned long size ); +Plat_AllocErrorFn g_AllocError = Plat_DefaultAllocErrorFn; + +PLATFORM_INTERFACE void* Plat_Alloc( unsigned long size ) +{ + void *pRet = g_pMemAlloc->Alloc( size ); + if ( pRet ) + { + return pRet; + } + else + { + g_AllocError( size ); + return 0; + } +} + + +PLATFORM_INTERFACE void* Plat_Realloc( void *ptr, unsigned long size ) +{ + void *pRet = g_pMemAlloc->Realloc( ptr, size ); + if ( pRet ) + { + return pRet; + } + else + { + g_AllocError( size ); + return 0; + } +} + + +PLATFORM_INTERFACE void Plat_Free( void *ptr ) +{ +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + g_pMemAlloc->Free( ptr ); +#else + free( ptr ); +#endif +} + + +PLATFORM_INTERFACE void Plat_SetAllocErrorFn( Plat_AllocErrorFn fn ) +{ + g_AllocError = fn; +} + +static char g_CmdLine[ 2048 ]; +PLATFORM_INTERFACE void Plat_SetCommandLine( const char *cmdLine ) +{ + strncpy( g_CmdLine, cmdLine, sizeof(g_CmdLine) ); + g_CmdLine[ sizeof(g_CmdLine) -1 ] = 0; +} + +PLATFORM_INTERFACE void Plat_SetCommandLineArgs( char **argv, int argc ) +{ + g_CmdLine[0] = 0; + for ( int i = 0; i < argc; i++ ) + { + strncat( g_CmdLine, argv[i], sizeof(g_CmdLine) - strlen(g_CmdLine) ); + } + + g_CmdLine[ sizeof(g_CmdLine) -1 ] = 0; +} + + +PLATFORM_INTERFACE const tchar *Plat_GetCommandLine() +{ + return g_CmdLine; +} + +PLATFORM_INTERFACE bool Is64BitOS() +{ +#if defined OSX + return true; +#elif defined LINUX + FILE *pp = popen( "uname -m", "r" ); + if ( pp != NULL ) + { + char rgchArchString[256]; + fgets( rgchArchString, sizeof( rgchArchString ), pp ); + pclose( pp ); + if ( !strncasecmp( rgchArchString, "x86_64", strlen( "x86_64" ) ) ) + return true; + } +#else + Assert( !"implement Is64BitOS" ); +#endif + return false; +} + + +bool Plat_IsInDebugSession() +{ +#if defined(OSX) + int mib[4]; + struct kinfo_proc info; + size_t size; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + size = sizeof(info); + info.kp_proc.p_flag = 0; + sysctl(mib,4,&info,&size,NULL,0); + bool result = ((info.kp_proc.p_flag & P_TRACED) == P_TRACED); + return result; +#elif defined(LINUX) + char s[256]; + snprintf(s, 256, "/proc/%d/cmdline", getppid()); + FILE * fp = fopen(s, "r"); + if (fp != NULL) + { + fread(s, 256, 1, fp); + fclose(fp); + return (0 == strncmp(s, "gdb", 3)); + } + return false; +#endif +} + + + +void Plat_ExitProcess( int nCode ) +{ + _exit( nCode ); +} + +static int s_nWatchDogTimerTimeScale = 0; +static bool s_bInittedWD = false; + + +static void InitWatchDogTimer( void ) +{ + if( !strstr( g_CmdLine, "-nowatchdog" ) ) + { +#ifdef _DEBUG + s_nWatchDogTimerTimeScale = 10; // debug is slow +#else + s_nWatchDogTimerTimeScale = 1; +#endif + + } + +} + +// watchdog timer support +void BeginWatchdogTimer( int nSecs ) +{ + if (! s_bInittedWD ) + { + s_bInittedWD = true; + InitWatchDogTimer(); + } + nSecs *= s_nWatchDogTimerTimeScale; + nSecs = MIN( nSecs, 5 * 60 ); // no more than 5 minutes no matter what + if ( nSecs ) + alarm( nSecs ); +} + +void EndWatchdogTimer( void ) +{ + alarm( 0 ); +} + +static CThreadMutex g_LocalTimeMutex; + + +void Plat_GetLocalTime( struct tm *pNow ) +{ + // We just provide a wrapper on this function so we can protect access to time() everywhere. + time_t ltime; + time( <ime ); + + Plat_ConvertToLocalTime( ltime, pNow ); +} + +void Plat_ConvertToLocalTime( uint64 nTime, struct tm *pNow ) +{ + // Since localtime() returns a global, we need to protect against multiple threads stomping it. + g_LocalTimeMutex.Lock(); + + time_t ltime = (time_t)nTime; + tm *pTime = localtime( <ime ); + if ( pTime ) + *pNow = *pTime; + else + memset( pNow, 0, sizeof( *pNow ) ); + + g_LocalTimeMutex.Unlock(); +} + +void Plat_GetTimeString( struct tm *pTime, char *pOut, int nMaxBytes ) +{ + g_LocalTimeMutex.Lock(); + + char *pStr = asctime( pTime ); + strncpy( pOut, pStr, nMaxBytes ); + pOut[nMaxBytes-1] = 0; + + g_LocalTimeMutex.Unlock(); +} + + +void Plat_gmtime( uint64 nTime, struct tm *pTime ) +{ + time_t tmtTime = nTime; + struct tm * tmp = gmtime( &tmtTime ); + * pTime = * tmp; +} + +#ifdef LINUX +size_t ApproximateProcessMemoryUsage( void ) +{ + int nRet = 0; + FILE *pFile = fopen( "/proc/self/statm", "r" ); + if ( pFile ) + { + int nSize, nTotalProgramSize, nResident, nResidentSetSize, nShare, nSharedPagesTotal, nDummy0; + if ( fscanf( pFile, "%d %d %d %d %d %d %d", &nSize, &nTotalProgramSize, &nResident, &nResidentSetSize, &nShare, &nSharedPagesTotal, &nDummy0 ) ) + { + nRet = 4096 * nSize; + } + fclose( pFile ); + } + return nRet; +} +#else + +size_t ApproximateProcessMemoryUsage( void ) +{ + return 0; +} + +#endif |