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