diff --git a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp index 163709d4c6..51422dac7f 100644 --- a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp +++ b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp @@ -1,15 +1,26 @@ #include "global.h" #include "ArchHooks_darwin.h" #include "RageLog.h" +#include "RageThreads.h" +#include "RageTimer.h" #include "RageUtil.h" #include "archutils/Darwin/Crash.h" #include "archutils/Unix/CrashHandler.h" #include "archutils/Unix/SignalHandler.h" #include "ProductInfo.h" #include +#include +#include #include #include #include +#include +#include + +#if 0 // Time critical stuff +static thread_time_constraint_policy g_oldttcpolicy; +static float g_fStartedTimeCritAt; +#endif static bool IsFatalSignal( int signal ) { @@ -55,6 +66,8 @@ ArchHooks_darwin::ArchHooks_darwin() SignalHandler::OnClose( DoCrashSignalHandler ); #endif + //TimeCritMutex = new RageMutex("TimeCritMutex"); + // CF*Copy* functions' return values need to be released, CF*Get* functions' do not. CFStringRef key = CFSTR( "ApplicationBundlePath" ); @@ -103,6 +116,11 @@ ArchHooks_darwin::ArchHooks_darwin() CFRelease( path ); } +ArchHooks_darwin::~ArchHooks_darwin() +{ + //delete TimeCritMutex; +} + void ArchHooks_darwin::DumpDebugInfo() { RString systemVersion; @@ -207,6 +225,53 @@ RString ArchHooks::GetPreferredLanguage() return ret.ToUpper(); } +void ArchHooks_darwin::EnterTimeCriticalSection() +{ +#if 0 + TimeCritMutex->Lock(); + + int mib[] = { CTL_HW, HW_BUS_FREQ }; + int miblen = ARRAYSIZE( mib ); + int bus_speed; + size_t len = sizeof (bus_speed); + if( sysctl( mib, miblen, &bus_speed, &len, NULL, 0 ) == -1 ) + { + LOG->Warn( "sysctl(HW_BUS_FREQ): %s", strerror(errno) ); + return; + } + + mach_msg_type_number_t cnt = THREAD_TIME_CONSTRAINT_POLICY_COUNT; + boolean_t bDefaults = false; + thread_policy_get( mach_thread_self(), THREAD_TIME_CONSTRAINT_POLICY, (int*)&g_oldttcpolicy, &cnt, &bDefaults ); + + /* We want to monopolize the CPU for a very short period of time. This means that the + * period doesn't really matter, and we don't want to be preempted. Set the period + * very high (~1 second), so that if we ever lose the CPU when we shouldn't, we can + * detect it and log it in ExitTimeCriticalSection(). */ + thread_time_constraint_policy ttcpolicy; + ttcpolicy.period = bus_speed; + ttcpolicy.computation = ttcpolicy.constraint = bus_speed/60; + ttcpolicy.preemptible = 0; + thread_policy_set( mach_thread_self(), THREAD_TIME_CONSTRAINT_POLICY, + (int*)&ttcpolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT ); + + g_fStartedTimeCritAt = RageTimer::GetTimeSinceStart(); +#endif +} + +void ArchHooks_darwin::ExitTimeCriticalSection() +{ +#if 0 + thread_policy_set( mach_thread_self(), THREAD_TIME_CONSTRAINT_POLICY, + (int*) &g_oldttcpolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT ); + TimeCritMutex->Unlock(); + + float fTimeCritLen = RageTimer::GetTimeSinceStart() - g_fStartedTimeCritAt; + if( fTimeCritLen > 0.1f ) + LOG->Warn( "Time-critical section lasted for %f", fTimeCritLen ); +#endif +} + int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate ) { static uint64_t iStartTime = mach_absolute_time(); diff --git a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h index e07fa88216..ba9ba21aac 100644 --- a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h +++ b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.h @@ -8,8 +8,14 @@ class ArchHooks_darwin : public ArchHooks { public: ArchHooks_darwin(); + ~ArchHooks_darwin(); void DumpDebugInfo(); RString GetPreferredLanguage(); + void EnterTimeCriticalSection(); + void ExitTimeCriticalSection(); + +protected: + //RageMutex *TimeCritMutex; }; #ifdef ARCH_HOOKS @@ -20,7 +26,7 @@ public: #endif /* ARCH_HOOKS_DARWIN_H */ /* - * (c) 2003-2006 Steve Checkoway + * (c) 2003-2005 Steve Checkoway * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a