diff options
Diffstat (limited to 'extern/bullet2/src/LinearMath/btQuickprof.cpp')
-rw-r--r-- | extern/bullet2/src/LinearMath/btQuickprof.cpp | 636 |
1 files changed, 430 insertions, 206 deletions
diff --git a/extern/bullet2/src/LinearMath/btQuickprof.cpp b/extern/bullet2/src/LinearMath/btQuickprof.cpp index d88d965a4cc..86fd1d78122 100644 --- a/extern/bullet2/src/LinearMath/btQuickprof.cpp +++ b/extern/bullet2/src/LinearMath/btQuickprof.cpp @@ -14,12 +14,7 @@ // Ogre (www.ogre3d.org). #include "btQuickprof.h" - -#ifndef BT_NO_PROFILE - - -static btClock gProfileClock; - +#include "btThreads.h" #ifdef __CELLOS_LV2__ #include <sys/sys_time.h> @@ -27,9 +22,13 @@ static btClock gProfileClock; #include <stdio.h> #endif -#if defined (SUNOS) || defined (__SUNOS__) +#if defined(SUNOS) || defined(__SUNOS__) #include <stdio.h> #endif +#ifdef __APPLE__ +#include <mach/mach_time.h> +#include <TargetConditionals.h> +#endif #if defined(WIN32) || defined(_WIN32) @@ -40,41 +39,46 @@ static btClock gProfileClock; #define NOIME #ifdef _XBOX - #include <Xtl.h> -#else //_XBOX - #include <windows.h> +#include <Xtl.h> +#else //_XBOX +#include <windows.h> -#if WINVER <0x0602 +#if WINVER < 0x0602 #define GetTickCount64 GetTickCount #endif -#endif //_XBOX +#endif //_XBOX #include <time.h> - -#else //_WIN32 +#else //_WIN32 #include <sys/time.h> -#endif //_WIN32 -#define mymin(a,b) (a > b ? a : b) +#ifdef BT_LINUX_REALTIME +//required linking against rt (librt) +#include <time.h> +#endif //BT_LINUX_REALTIME + +#endif //_WIN32 + +#define mymin(a, b) (a > b ? a : b) struct btClockData { - #ifdef BT_USE_WINDOWS_TIMERS LARGE_INTEGER mClockFrequency; LONGLONG mStartTick; - LONGLONG mPrevElapsedTime; LARGE_INTEGER mStartTime; #else #ifdef __CELLOS_LV2__ - uint64_t mStartTime; + uint64_t mStartTime; #else +#ifdef __APPLE__ + uint64_t mStartTimeNano; +#endif struct timeval mStartTime; #endif -#endif //__CELLOS_LV2__ - +#endif //__CELLOS_LV2__ }; ///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. @@ -104,23 +108,24 @@ btClock& btClock::operator=(const btClock& other) return *this; } - - /// Resets the initial reference time. +/// Resets the initial reference time. void btClock::reset() { #ifdef BT_USE_WINDOWS_TIMERS QueryPerformanceCounter(&m_data->mStartTime); m_data->mStartTick = GetTickCount64(); - m_data->mPrevElapsedTime = 0; #else #ifdef __CELLOS_LV2__ - typedef uint64_t ClockSize; + typedef uint64_t ClockSize; ClockSize newTime; //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - SYS_TIMEBASE_GET( newTime ); + SYS_TIMEBASE_GET(newTime); m_data->mStartTime = newTime; #else +#ifdef __APPLE__ + m_data->mStartTimeNano = mach_absolute_time(); +#endif gettimeofday(&m_data->mStartTime, 0); #endif #endif @@ -128,121 +133,136 @@ void btClock::reset() /// Returns the time in ms since the last call to reset or since /// the btClock was created. -unsigned long int btClock::getTimeMilliseconds() +unsigned long long int btClock::getTimeMilliseconds() { #ifdef BT_USE_WINDOWS_TIMERS LARGE_INTEGER currentTime; QueryPerformanceCounter(¤tTime); LONGLONG elapsedTime = currentTime.QuadPart - - m_data->mStartTime.QuadPart; - // Compute the number of millisecond ticks elapsed. + m_data->mStartTime.QuadPart; + // Compute the number of millisecond ticks elapsed. unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / - m_data->mClockFrequency.QuadPart); - // Check for unexpected leaps in the Win32 performance counter. - // (This is caused by unexpected data across the PCI to ISA - // bridge, aka south bridge. See Microsoft KB274323.) - unsigned long elapsedTicks = (unsigned long)(GetTickCount64() - m_data->mStartTick); - signed long msecOff = (signed long)(msecTicks - elapsedTicks); - if (msecOff < -100 || msecOff > 100) - { - // Adjust the starting time forwards. - LONGLONG msecAdjustment = mymin(msecOff * - m_data->mClockFrequency.QuadPart / 1000, elapsedTime - - m_data->mPrevElapsedTime); - m_data->mStartTime.QuadPart += msecAdjustment; - elapsedTime -= msecAdjustment; - - // Recompute the number of millisecond ticks elapsed. - msecTicks = (unsigned long)(1000 * elapsedTime / - m_data->mClockFrequency.QuadPart); - } - - // Store the current elapsed time for adjustments next time. - m_data->mPrevElapsedTime = elapsedTime; + m_data->mClockFrequency.QuadPart); - return msecTicks; + return msecTicks; #else #ifdef __CELLOS_LV2__ - uint64_t freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq) / 1000.0; - typedef uint64_t ClockSize; - ClockSize newTime; - SYS_TIMEBASE_GET( newTime ); - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - - return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + SYS_TIMEBASE_GET(newTime); + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); #else - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + - (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; -#endif //__CELLOS_LV2__ + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; +#endif //__CELLOS_LV2__ #endif } - /// Returns the time in us since the last call to reset or since - /// the Clock was created. -unsigned long int btClock::getTimeMicroseconds() +/// Returns the time in us since the last call to reset or since +/// the Clock was created. +unsigned long long int btClock::getTimeMicroseconds() { #ifdef BT_USE_WINDOWS_TIMERS - LARGE_INTEGER currentTime; - QueryPerformanceCounter(¤tTime); - LONGLONG elapsedTime = currentTime.QuadPart - - m_data->mStartTime.QuadPart; - - // Compute the number of millisecond ticks elapsed. - unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / - m_data->mClockFrequency.QuadPart); - - // Check for unexpected leaps in the Win32 performance counter. - // (This is caused by unexpected data across the PCI to ISA - // bridge, aka south bridge. See Microsoft KB274323.) - unsigned long elapsedTicks = (unsigned long)(GetTickCount64() - m_data->mStartTick); - signed long msecOff = (signed long)(msecTicks - elapsedTicks); - if (msecOff < -100 || msecOff > 100) - { - // Adjust the starting time forwards. - LONGLONG msecAdjustment = mymin(msecOff * - m_data->mClockFrequency.QuadPart / 1000, elapsedTime - - m_data->mPrevElapsedTime); - m_data->mStartTime.QuadPart += msecAdjustment; - elapsedTime -= msecAdjustment; - } - - // Store the current elapsed time for adjustments next time. - m_data->mPrevElapsedTime = elapsedTime; + //see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx + LARGE_INTEGER currentTime, elapsedTime; - // Convert to microseconds. - unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / - m_data->mClockFrequency.QuadPart); + QueryPerformanceCounter(¤tTime); + elapsedTime.QuadPart = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + elapsedTime.QuadPart *= 1000000; + elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; - return usecTicks; + return (unsigned long long)elapsedTime.QuadPart; #else #ifdef __CELLOS_LV2__ - uint64_t freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq)/ 1000000.0; - typedef uint64_t ClockSize; - ClockSize newTime; - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - SYS_TIMEBASE_GET( newTime ); - - return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1000000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET(newTime); + + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); #else - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + - (currentTime.tv_usec - m_data->mStartTime.tv_usec); -#endif//__CELLOS_LV2__ + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec); +#endif //__CELLOS_LV2__ #endif } +unsigned long long int btClock::getTimeNanoseconds() +{ +#ifdef BT_USE_WINDOWS_TIMERS + //see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx + LARGE_INTEGER currentTime, elapsedTime; + + QueryPerformanceCounter(¤tTime); + elapsedTime.QuadPart = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + elapsedTime.QuadPart *= 1000000000; + elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; + + return (unsigned long long)elapsedTime.QuadPart; +#else + +#ifdef __CELLOS_LV2__ + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1e9; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET(newTime); + + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); +#else +#ifdef __APPLE__ + uint64_t ticks = mach_absolute_time() - m_data->mStartTimeNano; + static long double conversion = 0.0L; + if (0.0L == conversion) + { + // attempt to get conversion to nanoseconds + mach_timebase_info_data_t info; + int err = mach_timebase_info(&info); + if (err) + { + btAssert(0); + conversion = 1.; + } + conversion = info.numer / info.denom; + } + return (ticks * conversion); +#else //__APPLE__ -/// Returns the time in s since the last call to reset or since +#ifdef BT_LINUX_REALTIME + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return 1000000000 * ts.tv_sec + ts.tv_nsec; +#else + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1e9 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec) * 1000; +#endif //BT_LINUX_REALTIME + +#endif //__APPLE__ +#endif //__CELLOS_LV2__ +#endif +} + +/// Returns the time in s since the last call to reset or since /// the Clock was created. btScalar btClock::getTimeSeconds() { @@ -250,22 +270,21 @@ btScalar btClock::getTimeSeconds() return btScalar(getTimeMicroseconds()) * microseconds_to_seconds; } +#ifndef BT_NO_PROFILE +static btClock gProfileClock; -inline void Profile_Get_Ticks(unsigned long int * ticks) +inline void Profile_Get_Ticks(unsigned long int* ticks) { - *ticks = gProfileClock.getTimeMicroseconds(); + *ticks = (unsigned long int)gProfileClock.getTimeMicroseconds(); } inline float Profile_Get_Tick_Rate(void) { -// return 1000000.f; + // return 1000000.f; return 1000.f; - } - - /*************************************************************************************************** ** ** CProfileNode @@ -281,35 +300,32 @@ inline float Profile_Get_Tick_Rate(void) * The name is assumed to be a static pointer, only the pointer is stored and compared for * * efficiency reasons. * *=============================================================================================*/ -CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) : - Name( name ), - TotalCalls( 0 ), - TotalTime( 0 ), - StartTime( 0 ), - RecursionCounter( 0 ), - Parent( parent ), - Child( NULL ), - Sibling( NULL ), - m_userPtr(0) +CProfileNode::CProfileNode(const char* name, CProfileNode* parent) : Name(name), + TotalCalls(0), + TotalTime(0), + StartTime(0), + RecursionCounter(0), + Parent(parent), + Child(NULL), + Sibling(NULL), + m_userPtr(0) { Reset(); } - -void CProfileNode::CleanupMemory() +void CProfileNode::CleanupMemory() { - delete ( Child); + delete (Child); Child = NULL; - delete ( Sibling); + delete (Sibling); Sibling = NULL; } -CProfileNode::~CProfileNode( void ) +CProfileNode::~CProfileNode(void) { CleanupMemory(); } - /*********************************************************************************************** * INPUT: * * name - static string pointer to the name of the node we are searching for * @@ -318,12 +334,14 @@ CProfileNode::~CProfileNode( void ) * All profile names are assumed to be static strings so this function uses pointer compares * * to find the named node. * *=============================================================================================*/ -CProfileNode * CProfileNode::Get_Sub_Node( const char * name ) +CProfileNode* CProfileNode::Get_Sub_Node(const char* name) { // Try to find this sub node - CProfileNode * child = Child; - while ( child ) { - if ( child->Name == name ) { + CProfileNode* child = Child; + while (child) + { + if (child->Name == name) + { return child; } child = child->Sibling; @@ -331,114 +349,211 @@ CProfileNode * CProfileNode::Get_Sub_Node( const char * name ) // We didn't find it, so add it - CProfileNode * node = new CProfileNode( name, this ); + CProfileNode* node = new CProfileNode(name, this); node->Sibling = Child; Child = node; return node; } - -void CProfileNode::Reset( void ) +void CProfileNode::Reset(void) { TotalCalls = 0; TotalTime = 0.0f; - - if ( Child ) { + if (Child) + { Child->Reset(); } - if ( Sibling ) { + if (Sibling) + { Sibling->Reset(); } } - -void CProfileNode::Call( void ) +void CProfileNode::Call(void) { TotalCalls++; - if (RecursionCounter++ == 0) { + if (RecursionCounter++ == 0) + { Profile_Get_Ticks(&StartTime); } } - -bool CProfileNode::Return( void ) +bool CProfileNode::Return(void) { - if ( --RecursionCounter == 0 && TotalCalls != 0 ) { + if (--RecursionCounter == 0 && TotalCalls != 0) + { unsigned long int time; Profile_Get_Ticks(&time); - time-=StartTime; + + time -= StartTime; TotalTime += (float)time / Profile_Get_Tick_Rate(); } - return ( RecursionCounter == 0 ); + return (RecursionCounter == 0); } - /*************************************************************************************************** ** ** CProfileIterator ** ***************************************************************************************************/ -CProfileIterator::CProfileIterator( CProfileNode * start ) +CProfileIterator::CProfileIterator(CProfileNode* start) { CurrentParent = start; CurrentChild = CurrentParent->Get_Child(); } - -void CProfileIterator::First(void) +void CProfileIterator::First(void) { CurrentChild = CurrentParent->Get_Child(); } - -void CProfileIterator::Next(void) +void CProfileIterator::Next(void) { CurrentChild = CurrentChild->Get_Sibling(); } - -bool CProfileIterator::Is_Done(void) +bool CProfileIterator::Is_Done(void) { return CurrentChild == NULL; } - -void CProfileIterator::Enter_Child( int index ) +void CProfileIterator::Enter_Child(int index) { CurrentChild = CurrentParent->Get_Child(); - while ( (CurrentChild != NULL) && (index != 0) ) { + while ((CurrentChild != NULL) && (index != 0)) + { index--; CurrentChild = CurrentChild->Get_Sibling(); } - if ( CurrentChild != NULL ) { + if (CurrentChild != NULL) + { CurrentParent = CurrentChild; CurrentChild = CurrentParent->Get_Child(); } } - -void CProfileIterator::Enter_Parent( void ) +void CProfileIterator::Enter_Parent(void) { - if ( CurrentParent->Get_Parent() != NULL ) { + if (CurrentParent->Get_Parent() != NULL) + { CurrentParent = CurrentParent->Get_Parent(); } CurrentChild = CurrentParent->Get_Child(); } - /*************************************************************************************************** ** ** CProfileManager ** ***************************************************************************************************/ -CProfileNode CProfileManager::Root( "Root", NULL ); -CProfileNode * CProfileManager::CurrentNode = &CProfileManager::Root; -int CProfileManager::FrameCounter = 0; -unsigned long int CProfileManager::ResetTime = 0; +CProfileNode gRoots[BT_QUICKPROF_MAX_THREAD_COUNT] = { + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL)}; + +CProfileNode* gCurrentNodes[BT_QUICKPROF_MAX_THREAD_COUNT] = + { + &gRoots[0], + &gRoots[1], + &gRoots[2], + &gRoots[3], + &gRoots[4], + &gRoots[5], + &gRoots[6], + &gRoots[7], + &gRoots[8], + &gRoots[9], + &gRoots[10], + &gRoots[11], + &gRoots[12], + &gRoots[13], + &gRoots[14], + &gRoots[15], + &gRoots[16], + &gRoots[17], + &gRoots[18], + &gRoots[19], + &gRoots[20], + &gRoots[21], + &gRoots[22], + &gRoots[23], + &gRoots[24], + &gRoots[25], + &gRoots[26], + &gRoots[27], + &gRoots[28], + &gRoots[29], + &gRoots[30], + &gRoots[31], + &gRoots[32], + &gRoots[33], + &gRoots[34], + &gRoots[35], + &gRoots[36], + &gRoots[37], + &gRoots[38], + &gRoots[39], + &gRoots[40], + &gRoots[41], + &gRoots[42], + &gRoots[43], + &gRoots[44], + &gRoots[45], + &gRoots[46], + &gRoots[47], + &gRoots[48], + &gRoots[49], + &gRoots[50], + &gRoots[51], + &gRoots[52], + &gRoots[53], + &gRoots[54], + &gRoots[55], + &gRoots[56], + &gRoots[57], + &gRoots[58], + &gRoots[59], + &gRoots[60], + &gRoots[61], + &gRoots[62], + &gRoots[63], +}; + +int CProfileManager::FrameCounter = 0; +unsigned long int CProfileManager::ResetTime = 0; +CProfileIterator* CProfileManager::Get_Iterator(void) +{ + int threadIndex = btQuickprofGetCurrentThreadIndex2(); + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) + return 0; + + return new CProfileIterator(&gRoots[threadIndex]); +} + +void CProfileManager::CleanupMemory(void) +{ + for (int i = 0; i < BT_QUICKPROF_MAX_THREAD_COUNT; i++) + { + gRoots[i].CleanupMemory(); + } +} /*********************************************************************************************** * CProfileManager::Start_Profile -- Begin a named profile * @@ -453,57 +568,66 @@ unsigned long int CProfileManager::ResetTime = 0; * The string used is assumed to be a static string; pointer compares are used throughout * * the profiling code for efficiency. * *=============================================================================================*/ -void CProfileManager::Start_Profile( const char * name ) +void CProfileManager::Start_Profile(const char* name) { - if (name != CurrentNode->Get_Name()) { - CurrentNode = CurrentNode->Get_Sub_Node( name ); + int threadIndex = btQuickprofGetCurrentThreadIndex2(); + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) + return; + + if (name != gCurrentNodes[threadIndex]->Get_Name()) + { + gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Sub_Node(name); } - CurrentNode->Call(); + gCurrentNodes[threadIndex]->Call(); } - /*********************************************************************************************** * CProfileManager::Stop_Profile -- Stop timing and record the results. * *=============================================================================================*/ -void CProfileManager::Stop_Profile( void ) +void CProfileManager::Stop_Profile(void) { + int threadIndex = btQuickprofGetCurrentThreadIndex2(); + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) + return; + // Return will indicate whether we should back up to our parent (we may // be profiling a recursive function) - if (CurrentNode->Return()) { - CurrentNode = CurrentNode->Get_Parent(); + if (gCurrentNodes[threadIndex]->Return()) + { + gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Parent(); } } - /*********************************************************************************************** * CProfileManager::Reset -- Reset the contents of the profiling system * * * * This resets everything except for the tree structure. All of the timing data is reset. * *=============================================================================================*/ -void CProfileManager::Reset( void ) +void CProfileManager::Reset(void) { gProfileClock.reset(); - Root.Reset(); - Root.Call(); + int threadIndex = btQuickprofGetCurrentThreadIndex2(); + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) + return; + gRoots[threadIndex].Reset(); + gRoots[threadIndex].Call(); FrameCounter = 0; Profile_Get_Ticks(&ResetTime); } - /*********************************************************************************************** * CProfileManager::Increment_Frame_Counter -- Increment the frame counter * *=============================================================================================*/ -void CProfileManager::Increment_Frame_Counter( void ) +void CProfileManager::Increment_Frame_Counter(void) { FrameCounter++; } - /*********************************************************************************************** * CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset * *=============================================================================================*/ -float CProfileManager::Get_Time_Since_Reset( void ) +float CProfileManager::Get_Time_Since_Reset(void) { unsigned long int time; Profile_Get_Ticks(&time); @@ -513,34 +637,34 @@ float CProfileManager::Get_Time_Since_Reset( void ) #include <stdio.h> -void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing) +void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing) { profileIterator->First(); if (profileIterator->Is_Done()) return; - float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); int i; int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); - for (i=0;i<spacing;i++) printf("."); + for (i = 0; i < spacing; i++) printf("."); printf("----------------------------------\n"); - for (i=0;i<spacing;i++) printf("."); - printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time ); + for (i = 0; i < spacing; i++) printf("."); + printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time); float totalTime = 0.f; - int numChildren = 0; - for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next()) { numChildren++; float current_total_time = profileIterator->Get_Current_Total_Time(); accumulated_time += current_total_time; float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; { - int i; for (i=0;i<spacing;i++) printf("."); + int i; + for (i = 0; i < spacing; i++) printf("."); } - printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); + printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n", i, profileIterator->Get_Current_Name(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls()); totalTime += current_total_time; //recurse into children } @@ -549,30 +673,130 @@ void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spaci { //printf("what's wrong\n"); } - for (i=0;i<spacing;i++) printf("."); - printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + for (i = 0; i < spacing; i++) printf("."); + printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:", parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); - for (i=0;i<numChildren;i++) + for (i = 0; i < numChildren; i++) { profileIterator->Enter_Child(i); - dumpRecursive(profileIterator,spacing+3); + dumpRecursive(profileIterator, spacing + 3); profileIterator->Enter_Parent(); } } - - -void CProfileManager::dumpAll() +void CProfileManager::dumpAll() { CProfileIterator* profileIterator = 0; profileIterator = CProfileManager::Get_Iterator(); - dumpRecursive(profileIterator,0); + dumpRecursive(profileIterator, 0); CProfileManager::Release_Iterator(profileIterator); } +void btEnterProfileZoneDefault(const char* name) +{ +} +void btLeaveProfileZoneDefault() +{ +} +#else +void btEnterProfileZoneDefault(const char* name) +{ +} +void btLeaveProfileZoneDefault() +{ +} +#endif //BT_NO_PROFILE + + +// clang-format off +#if defined(_WIN32) && (defined(__MINGW32__) || defined(__MINGW64__)) + #define BT_HAVE_TLS 1 +#elif __APPLE__ && !TARGET_OS_IPHONE + // TODO: Modern versions of iOS support TLS now with updated version checking. + #define BT_HAVE_TLS 1 +#elif __linux__ + #define BT_HAVE_TLS 1 +#endif + +// __thread is broken on Andorid clang until r12b. See +// https://github.com/android-ndk/ndk/issues/8 +#if defined(__ANDROID__) && defined(__clang__) + #if __has_include(<android/ndk-version.h>) + #include <android/ndk-version.h> + #endif // __has_include(<android/ndk-version.h>) + #if defined(__NDK_MAJOR__) && \ + ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) + #undef BT_HAVE_TLS + #endif +#endif // defined(__ANDROID__) && defined(__clang__) +// clang-format on + +unsigned int btQuickprofGetCurrentThreadIndex2() +{ + const unsigned int kNullIndex = ~0U; + +#if BT_THREADSAFE + return btGetCurrentThreadIndex(); +#else +#if defined(BT_HAVE_TLS) + static __thread unsigned int sThreadIndex = kNullIndex; +#elif defined(_WIN32) + __declspec(thread) static unsigned int sThreadIndex = kNullIndex; +#else + unsigned int sThreadIndex = 0; + return -1; +#endif + + static int gThreadCounter = 0; + + if (sThreadIndex == kNullIndex) + { + sThreadIndex = gThreadCounter++; + } + return sThreadIndex; +#endif //BT_THREADSAFE +} + +static btEnterProfileZoneFunc* bts_enterFunc = btEnterProfileZoneDefault; +static btLeaveProfileZoneFunc* bts_leaveFunc = btLeaveProfileZoneDefault; + +void btEnterProfileZone(const char* name) +{ + (bts_enterFunc)(name); +} +void btLeaveProfileZone() +{ + (bts_leaveFunc)(); +} + +btEnterProfileZoneFunc* btGetCurrentEnterProfileZoneFunc() +{ + return bts_enterFunc; +} +btLeaveProfileZoneFunc* btGetCurrentLeaveProfileZoneFunc() +{ + return bts_leaveFunc; +} + +void btSetCustomEnterProfileZoneFunc(btEnterProfileZoneFunc* enterFunc) +{ + bts_enterFunc = enterFunc; +} +void btSetCustomLeaveProfileZoneFunc(btLeaveProfileZoneFunc* leaveFunc) +{ + bts_leaveFunc = leaveFunc; +} -#endif //BT_NO_PROFILE +CProfileSample::CProfileSample(const char* name) +{ + btEnterProfileZone(name); +} + +CProfileSample::~CProfileSample(void) +{ + btLeaveProfileZone(); +} |