20 #include <sys/sys_time.h> 21 #include <sys/time_util.h> 25 #if defined(SUNOS) || defined(__SUNOS__) 29 #include <mach/mach_time.h> 30 #include <TargetConditionals.h> 33 #if defined(WIN32) || defined(_WIN32) 35 #define BT_USE_WINDOWS_TIMERS 36 #define WIN32_LEAN_AND_MEAN 47 #define GetTickCount64 GetTickCount 57 #ifdef BT_LINUX_REALTIME 60 #endif //BT_LINUX_REALTIME 64 #define mymin(a, b) (a > b ? a : b) 68 #ifdef BT_USE_WINDOWS_TIMERS 81 #endif //__CELLOS_LV2__ 88 #ifdef BT_USE_WINDOWS_TIMERS 114 #ifdef BT_USE_WINDOWS_TIMERS 118 #ifdef __CELLOS_LV2__ 123 SYS_TIMEBASE_GET(newTime);
127 m_data->mStartTimeNano = mach_absolute_time();
138 #ifdef BT_USE_WINDOWS_TIMERS 139 LARGE_INTEGER currentTime;
140 QueryPerformanceCounter(¤tTime);
141 LONGLONG elapsedTime = currentTime.QuadPart -
144 unsigned long msecTicks = (
unsigned long)(1000 * elapsedTime /
150 #ifdef __CELLOS_LV2__ 151 uint64_t freq = sys_time_get_timebase_frequency();
152 double dFreq = ((double)freq) / 1000.0;
155 SYS_TIMEBASE_GET(newTime);
161 struct timeval currentTime;
162 gettimeofday(¤tTime, 0);
165 #endif //__CELLOS_LV2__ 173 #ifdef BT_USE_WINDOWS_TIMERS 175 LARGE_INTEGER currentTime, elapsedTime;
177 QueryPerformanceCounter(¤tTime);
178 elapsedTime.QuadPart = currentTime.QuadPart -
180 elapsedTime.QuadPart *= 1000000;
183 return (
unsigned long long)elapsedTime.QuadPart;
186 #ifdef __CELLOS_LV2__ 187 uint64_t freq = sys_time_get_timebase_frequency();
188 double dFreq = ((double)freq) / 1000000.0;
192 SYS_TIMEBASE_GET(newTime);
197 struct timeval currentTime;
198 gettimeofday(¤tTime, 0);
201 #endif //__CELLOS_LV2__ 207 #ifdef BT_USE_WINDOWS_TIMERS 209 LARGE_INTEGER currentTime, elapsedTime;
211 QueryPerformanceCounter(¤tTime);
212 elapsedTime.QuadPart = currentTime.QuadPart -
214 elapsedTime.QuadPart *= 1000000000;
217 return (
unsigned long long)elapsedTime.QuadPart;
220 #ifdef __CELLOS_LV2__ 221 uint64_t freq = sys_time_get_timebase_frequency();
222 double dFreq = ((double)freq) / 1e9;
226 SYS_TIMEBASE_GET(newTime);
232 static long double conversion = 0.0L;
233 if (0.0L == conversion)
236 mach_timebase_info_data_t info;
237 int err = mach_timebase_info(&info);
243 conversion = info.numer / info.denom;
245 return (ticks * conversion);
249 #ifdef BT_LINUX_REALTIME 251 clock_gettime(CLOCK_REALTIME, &ts);
252 return 1000000000 * ts.tv_sec + ts.tv_nsec;
254 struct timeval currentTime;
255 gettimeofday(¤tTime, 0);
258 #endif //BT_LINUX_REALTIME 261 #endif //__CELLOS_LV2__ 273 #ifndef BT_NO_PROFILE 277 inline void Profile_Get_Ticks(
unsigned long int* ticks)
282 inline float Profile_Get_Tick_Rate(
void)
303 CProfileNode::CProfileNode(
const char* name, CProfileNode* parent) : Name(name),
316 void CProfileNode::CleanupMemory()
324 CProfileNode::~CProfileNode(
void)
337 CProfileNode* CProfileNode::Get_Sub_Node(
const char* name)
340 CProfileNode* child = Child;
343 if (child->Name == name)
347 child = child->Sibling;
352 CProfileNode* node =
new CProfileNode(name,
this);
353 node->Sibling = Child;
358 void CProfileNode::Reset(
void)
373 void CProfileNode::Call(
void)
376 if (RecursionCounter++ == 0)
378 Profile_Get_Ticks(&StartTime);
382 bool CProfileNode::Return(
void)
384 if (--RecursionCounter == 0 && TotalCalls != 0)
386 unsigned long int time;
387 Profile_Get_Ticks(&time);
390 TotalTime += (float)time / Profile_Get_Tick_Rate();
392 return (RecursionCounter == 0);
400 CProfileIterator::CProfileIterator(CProfileNode* start)
402 CurrentParent = start;
403 CurrentChild = CurrentParent->Get_Child();
406 void CProfileIterator::First(
void)
408 CurrentChild = CurrentParent->Get_Child();
411 void CProfileIterator::Next(
void)
413 CurrentChild = CurrentChild->Get_Sibling();
416 bool CProfileIterator::Is_Done(
void)
418 return CurrentChild == NULL;
421 void CProfileIterator::Enter_Child(
int index)
423 CurrentChild = CurrentParent->Get_Child();
424 while ((CurrentChild != NULL) && (index != 0))
427 CurrentChild = CurrentChild->Get_Sibling();
430 if (CurrentChild != NULL)
432 CurrentParent = CurrentChild;
433 CurrentChild = CurrentParent->Get_Child();
437 void CProfileIterator::Enter_Parent(
void)
439 if (CurrentParent->Get_Parent() != NULL)
441 CurrentParent = CurrentParent->Get_Parent();
443 CurrentChild = CurrentParent->Get_Child();
453 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
454 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
455 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
456 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
457 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
458 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
459 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
460 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
461 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
462 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
463 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
464 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
465 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
466 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
467 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL),
468 CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL), CProfileNode(
"Root", NULL)};
538 int CProfileManager::FrameCounter = 0;
539 unsigned long int CProfileManager::ResetTime = 0;
541 CProfileIterator* CProfileManager::Get_Iterator(
void)
547 return new CProfileIterator(&gRoots[threadIndex]);
550 void CProfileManager::CleanupMemory(
void)
554 gRoots[i].CleanupMemory();
571 void CProfileManager::Start_Profile(
const char* name)
577 if (name != gCurrentNodes[threadIndex]->Get_Name())
579 gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Sub_Node(name);
582 gCurrentNodes[threadIndex]->Call();
588 void CProfileManager::Stop_Profile(
void)
596 if (gCurrentNodes[threadIndex]->Return())
598 gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Parent();
607 void CProfileManager::Reset(
void)
609 gProfileClock.
reset();
613 gRoots[threadIndex].Reset();
614 gRoots[threadIndex].Call();
616 Profile_Get_Ticks(&ResetTime);
622 void CProfileManager::Increment_Frame_Counter(
void)
630 float CProfileManager::Get_Time_Since_Reset(
void)
632 unsigned long int time;
633 Profile_Get_Ticks(&time);
635 return (
float)time / Profile_Get_Tick_Rate();
640 void CProfileManager::dumpRecursive(CProfileIterator* profileIterator,
int spacing)
642 profileIterator->First();
643 if (profileIterator->Is_Done())
646 float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
648 int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
649 for (i = 0; i < spacing; i++) printf(
".");
650 printf(
"----------------------------------\n");
651 for (i = 0; i < spacing; i++) printf(
".");
652 printf(
"Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time);
653 float totalTime = 0.f;
657 for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next())
660 float current_total_time = profileIterator->Get_Current_Total_Time();
661 accumulated_time += current_total_time;
662 float fraction = parent_time >
SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
665 for (i = 0; i < spacing; i++) printf(
".");
667 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());
668 totalTime += current_total_time;
672 if (parent_time < accumulated_time)
676 for (i = 0; i < spacing; i++) printf(
".");
677 printf(
"%s (%.3f %%) :: %.3f ms\n",
"Unaccounted:", parent_time >
SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
679 for (i = 0; i < numChildren; i++)
681 profileIterator->Enter_Child(i);
682 dumpRecursive(profileIterator, spacing + 3);
683 profileIterator->Enter_Parent();
687 void CProfileManager::dumpAll()
689 CProfileIterator* profileIterator = 0;
690 profileIterator = CProfileManager::Get_Iterator();
692 dumpRecursive(profileIterator, 0);
694 CProfileManager::Release_Iterator(profileIterator);
712 #endif //BT_NO_PROFILE 716 #if defined(_WIN32) && (defined(__MINGW32__) || defined(__MINGW64__)) 717 #define BT_HAVE_TLS 1 718 #elif __APPLE__ && !TARGET_OS_IPHONE 720 #define BT_HAVE_TLS 1 722 #define BT_HAVE_TLS 1 727 #if defined(__ANDROID__) && defined(__clang__) 728 #if __has_include(<android/ndk-version.h>) 729 #include <android/ndk-version.h> 730 #endif // __has_include(<android/ndk-version.h>) 731 #if defined(__NDK_MAJOR__) && \ 732 ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) 735 #endif // defined(__ANDROID__) && defined(__clang__) 740 const unsigned int kNullIndex = ~0
U;
745 #if defined(BT_HAVE_TLS) 746 static __thread
unsigned int sThreadIndex = kNullIndex;
747 #elif defined(_WIN32) 748 __declspec(thread)
static unsigned int sThreadIndex = kNullIndex;
750 unsigned int sThreadIndex = 0;
756 if (sThreadIndex == kNullIndex)
761 #endif //BT_THREADSAFE
CProfileSample(const char *name)
unsigned long long int uint64_t
void() btEnterProfileZoneFunc(const char *msg)
btEnterProfileZoneFunc * btGetCurrentEnterProfileZoneFunc()
btScalar getTimeSeconds()
Returns the time in s since the last call to reset or since the Clock was created.
unsigned int btQuickprofGetCurrentThreadIndex2()
unsigned long long int getTimeNanoseconds()
The btClock is a portable basic clock that measures accurate time in seconds, use for profiling...
void reset()
Resets the initial reference time.
void btSetCustomEnterProfileZoneFunc(btEnterProfileZoneFunc *enterFunc)
btLeaveProfileZoneFunc * btGetCurrentLeaveProfileZoneFunc()
void btEnterProfileZone(const char *name)
btClock()
The btClock is a portable basic clock that measures accurate time in seconds, use for profiling...
struct btClockData * m_data
static ThreadsafeCounter gThreadCounter
void btLeaveProfileZone()
unsigned long long int getTimeMicroseconds()
Returns the time in us since the last call to reset or since the Clock was created.
void btSetCustomLeaveProfileZoneFunc(btLeaveProfileZoneFunc *leaveFunc)
btClock & operator=(const btClock &other)
unsigned long long int getTimeMilliseconds()
Returns the time in ms since the last call to reset or since the btClock was created.
const unsigned int BT_QUICKPROF_MAX_THREAD_COUNT
static btEnterProfileZoneFunc * bts_enterFunc
void() btLeaveProfileZoneFunc()
void btLeaveProfileZoneDefault()
LARGE_INTEGER mClockFrequency
unsigned int btGetCurrentThreadIndex()
static btLeaveProfileZoneFunc * bts_leaveFunc
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
void btEnterProfileZoneDefault(const char *name)