btQuickprof.h

Go to the documentation of this file.
00001 
00002 /***************************************************************************************************
00003 **
00004 ** Real-Time Hierarchical Profiling for Game Programming Gems 3
00005 **
00006 ** by Greg Hjelstrom & Byon Garrabrant
00007 **
00008 ***************************************************************************************************/
00009 
00010 // Credits: The Clock class was inspired by the Timer classes in 
00011 // Ogre (www.ogre3d.org).
00012 
00013 
00014 
00015 #ifndef QUICK_PROF_H
00016 #define QUICK_PROF_H
00017 
00018 //To disable built-in profiling, please comment out next line
00019 //#define BT_NO_PROFILE 1
00020 #ifndef BT_NO_PROFILE
00021 
00022 #include "btScalar.h"
00023 #include "btAlignedAllocator.h"
00024 #include <new>
00025 
00026 
00027 
00028 
00029 //if you don't need btClock, you can comment next line
00030 #define USE_BT_CLOCK 1
00031 
00032 #ifdef USE_BT_CLOCK
00033 #ifdef __CELLOS_LV2__
00034 #include <sys/sys_time.h>
00035 #include <sys/time_util.h>
00036 #include <stdio.h>
00037 #endif
00038 
00039 #if defined (SUNOS) || defined (__SUNOS__) 
00040 #include <stdio.h> 
00041 #endif
00042 
00043 #if defined(WIN32) || defined(_WIN32)
00044 
00045 #define USE_WINDOWS_TIMERS 
00046 #define WIN32_LEAN_AND_MEAN 
00047 #define NOWINRES 
00048 #define NOMCX 
00049 #define NOIME 
00050 #ifdef _XBOX
00051 #include <Xtl.h>
00052 #else
00053 #include <windows.h>
00054 #endif
00055 #include <time.h>
00056 
00057 #else
00058 #include <sys/time.h>
00059 #endif
00060 
00061 #define mymin(a,b) (a > b ? a : b)
00062 
00064 class btClock
00065 {
00066 public:
00067         btClock()
00068         {
00069 #ifdef USE_WINDOWS_TIMERS
00070                 QueryPerformanceFrequency(&mClockFrequency);
00071 #endif
00072                 reset();
00073         }
00074 
00075         ~btClock()
00076         {
00077         }
00078 
00080         void reset()
00081         {
00082 #ifdef USE_WINDOWS_TIMERS
00083                 QueryPerformanceCounter(&mStartTime);
00084                 mStartTick = GetTickCount();
00085                 mPrevElapsedTime = 0;
00086 #else
00087 #ifdef __CELLOS_LV2__
00088 
00089                 typedef uint64_t  ClockSize;
00090                 ClockSize newTime;
00091                 //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
00092                 SYS_TIMEBASE_GET( newTime );
00093                 mStartTime = newTime;
00094 #else
00095                 gettimeofday(&mStartTime, 0);
00096 #endif
00097 
00098 #endif
00099         }
00100 
00103         unsigned long int getTimeMilliseconds()
00104         {
00105 #ifdef USE_WINDOWS_TIMERS
00106                 LARGE_INTEGER currentTime;
00107                 QueryPerformanceCounter(&currentTime);
00108                 LONGLONG elapsedTime = currentTime.QuadPart - 
00109                         mStartTime.QuadPart;
00110 
00111                 // Compute the number of millisecond ticks elapsed.
00112                 unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
00113                         mClockFrequency.QuadPart);
00114 
00115                 // Check for unexpected leaps in the Win32 performance counter.  
00116                 // (This is caused by unexpected data across the PCI to ISA 
00117                 // bridge, aka south bridge.  See Microsoft KB274323.)
00118                 unsigned long elapsedTicks = GetTickCount() - mStartTick;
00119                 signed long msecOff = (signed long)(msecTicks - elapsedTicks);
00120                 if (msecOff < -100 || msecOff > 100)
00121                 {
00122                         // Adjust the starting time forwards.
00123                         LONGLONG msecAdjustment = mymin(msecOff * 
00124                                 mClockFrequency.QuadPart / 1000, elapsedTime - 
00125                                 mPrevElapsedTime);
00126                         mStartTime.QuadPart += msecAdjustment;
00127                         elapsedTime -= msecAdjustment;
00128 
00129                         // Recompute the number of millisecond ticks elapsed.
00130                         msecTicks = (unsigned long)(1000 * elapsedTime / 
00131                                 mClockFrequency.QuadPart);
00132                 }
00133 
00134                 // Store the current elapsed time for adjustments next time.
00135                 mPrevElapsedTime = elapsedTime;
00136 
00137                 return msecTicks;
00138 #else
00139 
00140 #ifdef __CELLOS_LV2__
00141                 uint64_t freq=sys_time_get_timebase_frequency();
00142                 double dFreq=((double) freq) / 1000.0;
00143                 typedef uint64_t  ClockSize;
00144                 ClockSize newTime;
00145                 SYS_TIMEBASE_GET( newTime );
00146                 //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
00147 
00148                 return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
00149 #else
00150 
00151                 struct timeval currentTime;
00152                 gettimeofday(&currentTime, 0);
00153                 return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 + 
00154                         (currentTime.tv_usec - mStartTime.tv_usec) / 1000;
00155 #endif //__CELLOS_LV2__
00156 #endif
00157         }
00158 
00161         unsigned long int getTimeMicroseconds()
00162         {
00163 #ifdef USE_WINDOWS_TIMERS
00164                 LARGE_INTEGER currentTime;
00165                 QueryPerformanceCounter(&currentTime);
00166                 LONGLONG elapsedTime = currentTime.QuadPart - 
00167                         mStartTime.QuadPart;
00168 
00169                 // Compute the number of millisecond ticks elapsed.
00170                 unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
00171                         mClockFrequency.QuadPart);
00172 
00173                 // Check for unexpected leaps in the Win32 performance counter.  
00174                 // (This is caused by unexpected data across the PCI to ISA 
00175                 // bridge, aka south bridge.  See Microsoft KB274323.)
00176                 unsigned long elapsedTicks = GetTickCount() - mStartTick;
00177                 signed long msecOff = (signed long)(msecTicks - elapsedTicks);
00178                 if (msecOff < -100 || msecOff > 100)
00179                 {
00180                         // Adjust the starting time forwards.
00181                         LONGLONG msecAdjustment = mymin(msecOff * 
00182                                 mClockFrequency.QuadPart / 1000, elapsedTime - 
00183                                 mPrevElapsedTime);
00184                         mStartTime.QuadPart += msecAdjustment;
00185                         elapsedTime -= msecAdjustment;
00186                 }
00187 
00188                 // Store the current elapsed time for adjustments next time.
00189                 mPrevElapsedTime = elapsedTime;
00190 
00191                 // Convert to microseconds.
00192                 unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / 
00193                         mClockFrequency.QuadPart);
00194 
00195                 return usecTicks;
00196 #else
00197 
00198 #ifdef __CELLOS_LV2__
00199                 uint64_t freq=sys_time_get_timebase_frequency();
00200                 double dFreq=((double) freq)/ 1000000.0;
00201                 typedef uint64_t  ClockSize;
00202                 ClockSize newTime;
00203                 //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
00204                 SYS_TIMEBASE_GET( newTime );
00205 
00206                 return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
00207 #else
00208 
00209                 struct timeval currentTime;
00210                 gettimeofday(&currentTime, 0);
00211                 return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 + 
00212                         (currentTime.tv_usec - mStartTime.tv_usec);
00213 #endif//__CELLOS_LV2__
00214 #endif 
00215         }
00216 
00217 private:
00218 #ifdef USE_WINDOWS_TIMERS
00219         LARGE_INTEGER mClockFrequency;
00220         DWORD mStartTick;
00221         LONGLONG mPrevElapsedTime;
00222         LARGE_INTEGER mStartTime;
00223 #else
00224 #ifdef __CELLOS_LV2__
00225         uint64_t        mStartTime;
00226 #else
00227         struct timeval mStartTime;
00228 #endif
00229 #endif //__CELLOS_LV2__
00230 
00231 };
00232 
00233 #endif //USE_BT_CLOCK
00234 
00235 
00236 
00237 
00239 class   CProfileNode {
00240 
00241 public:
00242         CProfileNode( const char * name, CProfileNode * parent );
00243         ~CProfileNode( void );
00244 
00245         CProfileNode * Get_Sub_Node( const char * name );
00246 
00247         CProfileNode * Get_Parent( void )               { return Parent; }
00248         CProfileNode * Get_Sibling( void )              { return Sibling; }
00249         CProfileNode * Get_Child( void )                        { return Child; }
00250 
00251         void                            CleanupMemory();
00252         void                            Reset( void );
00253         void                            Call( void );
00254         bool                            Return( void );
00255 
00256         const char *    Get_Name( void )                                { return Name; }
00257         int                             Get_Total_Calls( void )         { return TotalCalls; }
00258         float                           Get_Total_Time( void )          { return TotalTime; }
00259 
00260 protected:
00261 
00262         const char *    Name;
00263         int                             TotalCalls;
00264         float                           TotalTime;
00265         unsigned long int                       StartTime;
00266         int                             RecursionCounter;
00267 
00268         CProfileNode *  Parent;
00269         CProfileNode *  Child;
00270         CProfileNode *  Sibling;
00271 };
00272 
00274 class CProfileIterator
00275 {
00276 public:
00277         // Access all the children of the current parent
00278         void                            First(void);
00279         void                            Next(void);
00280         bool                            Is_Done(void);
00281         bool                Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
00282 
00283         void                            Enter_Child( int index );               // Make the given child the new parent
00284         void                            Enter_Largest_Child( void );    // Make the largest child the new parent
00285         void                            Enter_Parent( void );                   // Make the current parent's parent the new parent
00286 
00287         // Access the current child
00288         const char *    Get_Current_Name( void )                        { return CurrentChild->Get_Name(); }
00289         int                             Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
00290         float                           Get_Current_Total_Time( void )  { return CurrentChild->Get_Total_Time(); }
00291 
00292         // Access the current parent
00293         const char *    Get_Current_Parent_Name( void )                 { return CurrentParent->Get_Name(); }
00294         int                             Get_Current_Parent_Total_Calls( void )  { return CurrentParent->Get_Total_Calls(); }
00295         float                           Get_Current_Parent_Total_Time( void )   { return CurrentParent->Get_Total_Time(); }
00296 
00297 protected:
00298 
00299         CProfileNode *  CurrentParent;
00300         CProfileNode *  CurrentChild;
00301 
00302         CProfileIterator( CProfileNode * start );
00303         friend  class           CProfileManager;
00304 };
00305 
00306 
00308 class   CProfileManager {
00309 public:
00310         static  void                                            Start_Profile( const char * name );
00311         static  void                                            Stop_Profile( void );
00312 
00313         static  void                                            CleanupMemory(void)
00314         {
00315                 Root.CleanupMemory();
00316         }
00317 
00318         static  void                                            Reset( void );
00319         static  void                                            Increment_Frame_Counter( void );
00320         static  int                                             Get_Frame_Count_Since_Reset( void )             { return FrameCounter; }
00321         static  float                                           Get_Time_Since_Reset( void );
00322 
00323         static  CProfileIterator *      Get_Iterator( void )    
00324         { 
00325                 
00326                 return new CProfileIterator( &Root ); 
00327         }
00328         static  void                                            Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
00329 
00330         static void     dumpRecursive(CProfileIterator* profileIterator, int spacing);
00331 
00332         static void     dumpAll();
00333 
00334 private:
00335         static  CProfileNode                    Root;
00336         static  CProfileNode *                  CurrentNode;
00337         static  int                                             FrameCounter;
00338         static  unsigned long int                                       ResetTime;
00339 };
00340 
00341 
00344 class   CProfileSample {
00345 public:
00346         CProfileSample( const char * name )
00347         { 
00348                 CProfileManager::Start_Profile( name ); 
00349         }
00350 
00351         ~CProfileSample( void )                                 
00352         { 
00353                 CProfileManager::Stop_Profile(); 
00354         }
00355 };
00356 
00357 
00358 #define BT_PROFILE( name )                      CProfileSample __profile( name )
00359 
00360 #else
00361 
00362 #define BT_PROFILE( name )
00363 
00364 #endif //#ifndef BT_NO_PROFILE
00365 
00366 
00367 
00368 #endif //QUICK_PROF_H
00369 
00370 

Generated on Mon Feb 15 22:17:05 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1