Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics_new/src/bullet/LinearMath/btQuickprof.h @ 2119

Last change on this file since 2119 was 2119, checked in by rgrieder, 16 years ago

Merged physics branch into physics_new branch.

  • Property svn:eol-style set to native
File size: 9.1 KB
Line 
1
2/***************************************************************************************************
3**
4** Real-Time Hierarchical Profiling for Game Programming Gems 3
5**
6** by Greg Hjelstrom & Byon Garrabrant
7**
8***************************************************************************************************/
9
10// Credits: The Clock class was inspired by the Timer classes in
11// Ogre (www.ogre3d.org).
12
13#ifndef QUICK_PROF_H
14#define QUICK_PROF_H
15
16#include "btScalar.h"
17#include "LinearMath/btAlignedAllocator.h"
18#include <new>
19//To disable built-in profiling, please comment out next line
20//#define BT_NO_PROFILE 1
21
22
23//if you don't need btClock, you can comment next line
24#define USE_BT_CLOCK 1
25
26#ifdef USE_BT_CLOCK
27#ifdef __CELLOS_LV2__
28#include <sys/sys_time.h>
29#include <sys/time_util.h>
30#include <stdio.h>
31#endif
32
33#if defined (SUNOS) || defined (__SUNOS__)
34#include <stdio.h> 
35#endif
36
37#if defined(WIN32) || defined(_WIN32)
38
39#define USE_WINDOWS_TIMERS
40#define WIN32_LEAN_AND_MEAN
41#define NOWINRES
42#define NOMCX
43#define NOIME
44#ifdef _XBOX
45#include <Xtl.h>
46#else
47#include <windows.h>
48#endif
49#include <time.h>
50
51#else
52#include <sys/time.h>
53#endif
54
55#define mymin(a,b) (a > b ? a : b)
56
57///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
58class btClock
59{
60public:
61        btClock()
62        {
63#ifdef USE_WINDOWS_TIMERS
64                QueryPerformanceFrequency(&mClockFrequency);
65#endif
66                reset();
67        }
68
69        ~btClock()
70        {
71        }
72
73        /// Resets the initial reference time.
74        void reset()
75        {
76#ifdef USE_WINDOWS_TIMERS
77                QueryPerformanceCounter(&mStartTime);
78                mStartTick = GetTickCount();
79                mPrevElapsedTime = 0;
80#else
81#ifdef __CELLOS_LV2__
82
83                typedef uint64_t  ClockSize;
84                ClockSize newTime;
85                //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
86                SYS_TIMEBASE_GET( newTime );
87                mStartTime = newTime;
88#else
89                gettimeofday(&mStartTime, 0);
90#endif
91
92#endif
93        }
94
95        /// Returns the time in ms since the last call to reset or since
96        /// the btClock was created.
97        unsigned long int getTimeMilliseconds()
98        {
99#ifdef USE_WINDOWS_TIMERS
100                LARGE_INTEGER currentTime;
101                QueryPerformanceCounter(&currentTime);
102                LONGLONG elapsedTime = currentTime.QuadPart - 
103                        mStartTime.QuadPart;
104
105                // Compute the number of millisecond ticks elapsed.
106                unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
107                        mClockFrequency.QuadPart);
108
109                // Check for unexpected leaps in the Win32 performance counter. 
110                // (This is caused by unexpected data across the PCI to ISA
111                // bridge, aka south bridge.  See Microsoft KB274323.)
112                unsigned long elapsedTicks = GetTickCount() - mStartTick;
113                signed long msecOff = (signed long)(msecTicks - elapsedTicks);
114                if (msecOff < -100 || msecOff > 100)
115                {
116                        // Adjust the starting time forwards.
117                        LONGLONG msecAdjustment = mymin(msecOff * 
118                                mClockFrequency.QuadPart / 1000, elapsedTime - 
119                                mPrevElapsedTime);
120                        mStartTime.QuadPart += msecAdjustment;
121                        elapsedTime -= msecAdjustment;
122
123                        // Recompute the number of millisecond ticks elapsed.
124                        msecTicks = (unsigned long)(1000 * elapsedTime / 
125                                mClockFrequency.QuadPart);
126                }
127
128                // Store the current elapsed time for adjustments next time.
129                mPrevElapsedTime = elapsedTime;
130
131                return msecTicks;
132#else
133
134#ifdef __CELLOS_LV2__
135                uint64_t freq=sys_time_get_timebase_frequency();
136                double dFreq=((double) freq) / 1000.0;
137                typedef uint64_t  ClockSize;
138                ClockSize newTime;
139                SYS_TIMEBASE_GET( newTime );
140                //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
141
142                return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
143#else
144
145                struct timeval currentTime;
146                gettimeofday(&currentTime, 0);
147                return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 + 
148                        (currentTime.tv_usec - mStartTime.tv_usec) / 1000;
149#endif //__CELLOS_LV2__
150#endif
151        }
152
153        /// Returns the time in us since the last call to reset or since
154        /// the Clock was created.
155        unsigned long int getTimeMicroseconds()
156        {
157#ifdef USE_WINDOWS_TIMERS
158                LARGE_INTEGER currentTime;
159                QueryPerformanceCounter(&currentTime);
160                LONGLONG elapsedTime = currentTime.QuadPart - 
161                        mStartTime.QuadPart;
162
163                // Compute the number of millisecond ticks elapsed.
164                unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
165                        mClockFrequency.QuadPart);
166
167                // Check for unexpected leaps in the Win32 performance counter. 
168                // (This is caused by unexpected data across the PCI to ISA
169                // bridge, aka south bridge.  See Microsoft KB274323.)
170                unsigned long elapsedTicks = GetTickCount() - mStartTick;
171                signed long msecOff = (signed long)(msecTicks - elapsedTicks);
172                if (msecOff < -100 || msecOff > 100)
173                {
174                        // Adjust the starting time forwards.
175                        LONGLONG msecAdjustment = mymin(msecOff * 
176                                mClockFrequency.QuadPart / 1000, elapsedTime - 
177                                mPrevElapsedTime);
178                        mStartTime.QuadPart += msecAdjustment;
179                        elapsedTime -= msecAdjustment;
180                }
181
182                // Store the current elapsed time for adjustments next time.
183                mPrevElapsedTime = elapsedTime;
184
185                // Convert to microseconds.
186                unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / 
187                        mClockFrequency.QuadPart);
188
189                return usecTicks;
190#else
191
192#ifdef __CELLOS_LV2__
193                uint64_t freq=sys_time_get_timebase_frequency();
194                double dFreq=((double) freq)/ 1000000.0;
195                typedef uint64_t  ClockSize;
196                ClockSize newTime;
197                //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
198                SYS_TIMEBASE_GET( newTime );
199
200                return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
201#else
202
203                struct timeval currentTime;
204                gettimeofday(&currentTime, 0);
205                return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 + 
206                        (currentTime.tv_usec - mStartTime.tv_usec);
207#endif//__CELLOS_LV2__
208#endif
209        }
210
211private:
212#ifdef USE_WINDOWS_TIMERS
213        LARGE_INTEGER mClockFrequency;
214        DWORD mStartTick;
215        LONGLONG mPrevElapsedTime;
216        LARGE_INTEGER mStartTime;
217#else
218#ifdef __CELLOS_LV2__
219        uint64_t        mStartTime;
220#else
221        struct timeval mStartTime;
222#endif
223#endif //__CELLOS_LV2__
224
225};
226
227#endif //USE_BT_CLOCK
228
229
230
231
232///A node in the Profile Hierarchy Tree
233class   CProfileNode {
234
235public:
236        CProfileNode( const char * name, CProfileNode * parent );
237        ~CProfileNode( void );
238
239        CProfileNode * Get_Sub_Node( const char * name );
240
241        CProfileNode * Get_Parent( void )               { return Parent; }
242        CProfileNode * Get_Sibling( void )              { return Sibling; }
243        CProfileNode * Get_Child( void )                        { return Child; }
244
245        void                            CleanupMemory();
246        void                            Reset( void );
247        void                            Call( void );
248        bool                            Return( void );
249
250        const char *    Get_Name( void )                                { return Name; }
251        int                             Get_Total_Calls( void )         { return TotalCalls; }
252        float                           Get_Total_Time( void )          { return TotalTime; }
253
254protected:
255
256        const char *    Name;
257        int                             TotalCalls;
258        float                           TotalTime;
259        unsigned long int                       StartTime;
260        int                             RecursionCounter;
261
262        CProfileNode *  Parent;
263        CProfileNode *  Child;
264        CProfileNode *  Sibling;
265};
266
267///An iterator to navigate through the tree
268class CProfileIterator
269{
270public:
271        // Access all the children of the current parent
272        void                            First(void);
273        void                            Next(void);
274        bool                            Is_Done(void);
275        bool                Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
276
277        void                            Enter_Child( int index );               // Make the given child the new parent
278        void                            Enter_Largest_Child( void );    // Make the largest child the new parent
279        void                            Enter_Parent( void );                   // Make the current parent's parent the new parent
280
281        // Access the current child
282        const char *    Get_Current_Name( void )                        { return CurrentChild->Get_Name(); }
283        int                             Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
284        float                           Get_Current_Total_Time( void )  { return CurrentChild->Get_Total_Time(); }
285
286        // Access the current parent
287        const char *    Get_Current_Parent_Name( void )                 { return CurrentParent->Get_Name(); }
288        int                             Get_Current_Parent_Total_Calls( void )  { return CurrentParent->Get_Total_Calls(); }
289        float                           Get_Current_Parent_Total_Time( void )   { return CurrentParent->Get_Total_Time(); }
290
291protected:
292
293        CProfileNode *  CurrentParent;
294        CProfileNode *  CurrentChild;
295
296        CProfileIterator( CProfileNode * start );
297        friend  class           CProfileManager;
298};
299
300
301///The Manager for the Profile system
302class   CProfileManager {
303public:
304        static  void                                            Start_Profile( const char * name );
305        static  void                                            Stop_Profile( void );
306
307        static  void                                            CleanupMemory(void)
308        {
309                Root.CleanupMemory();
310        }
311
312        static  void                                            Reset( void );
313        static  void                                            Increment_Frame_Counter( void );
314        static  int                                             Get_Frame_Count_Since_Reset( void )             { return FrameCounter; }
315        static  float                                           Get_Time_Since_Reset( void );
316
317        static  CProfileIterator *      Get_Iterator( void )   
318        { 
319               
320                return new CProfileIterator( &Root ); 
321        }
322        static  void                                            Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
323
324private:
325        static  CProfileNode                    Root;
326        static  CProfileNode *                  CurrentNode;
327        static  int                                             FrameCounter;
328        static  unsigned long int                                       ResetTime;
329};
330
331
332///ProfileSampleClass is a simple way to profile a function's scope
333///Use the BT_PROFILE macro at the start of scope to time
334class   CProfileSample {
335public:
336        CProfileSample( const char * name )
337        { 
338                CProfileManager::Start_Profile( name ); 
339        }
340
341        ~CProfileSample( void )                                 
342        { 
343                CProfileManager::Stop_Profile(); 
344        }
345};
346
347#if !defined(BT_NO_PROFILE)
348#define BT_PROFILE( name )                      CProfileSample __profile( name )
349#else
350#define BT_PROFILE( name )
351#endif
352
353
354
355
356#endif //QUICK_PROF_H
357
358
Note: See TracBrowser for help on using the repository browser.