2 Stopwatch for timing and profiling for the Bullet Physics Library, http://bulletphysics.org
\r
3 Copyright (c) 2003-2011 Erwin Coumans
\r
5 This software is provided 'as-is', without any express or implied warranty.
\r
6 In no event will the authors be held liable for any damages arising from the use of this software.
\r
7 Permission is granted to anyone to use this software for any purpose,
\r
8 including commercial applications, and to alter it and redistribute it freely,
\r
9 subject to the following restrictions:
\r
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
\r
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
\r
13 3. This notice may not be removed or altered from any source distribution.
\r
16 #include "btStopwatch.h"
\r
19 #ifdef __CELLOS_LV2__
\r
20 #include <sys/sys_time.h>
\r
21 #include <sys/time_util.h>
\r
25 #if defined (SUNOS) || defined (__SUNOS__)
\r
29 #if defined(WIN32) || defined(_WIN32)
\r
31 #define BT_USE_WINDOWS_TIMERS
\r
32 #define WIN32_LEAN_AND_MEAN
\r
40 #include <windows.h>
\r
47 #include <sys/time.h>
\r
50 #define mymin(a,b) (a > b ? a : b)
\r
52 struct btStopwatchData
\r
55 #ifdef BT_USE_WINDOWS_TIMERS
\r
56 LARGE_INTEGER mClockFrequency;
\r
58 LONGLONG mPrevElapsedTime;
\r
59 LARGE_INTEGER mStartTime;
\r
61 #ifdef __CELLOS_LV2__
\r
62 uint64_t mStartTime;
\r
64 struct timeval mStartTime;
\r
66 #endif //__CELLOS_LV2__
\r
71 btStopwatch::btStopwatch()
\r
73 m_data = new btStopwatchData;
\r
74 #ifdef BT_USE_WINDOWS_TIMERS
\r
75 QueryPerformanceFrequency(&m_data->mClockFrequency);
\r
80 btStopwatch::~btStopwatch()
\r
85 btStopwatch::btStopwatch(const btStopwatch& other)
\r
87 m_data = new btStopwatchData;
\r
88 *m_data = *other.m_data;
\r
91 btStopwatch& btStopwatch::operator=(const btStopwatch& other)
\r
93 *m_data = *other.m_data;
\r
98 /// Resets the initial reference time.
\r
99 void btStopwatch::reset()
\r
101 #ifdef BT_USE_WINDOWS_TIMERS
\r
102 QueryPerformanceCounter(&m_data->mStartTime);
\r
103 m_data->mStartTick = GetTickCount();
\r
104 m_data->mPrevElapsedTime = 0;
\r
106 #ifdef __CELLOS_LV2__
\r
108 typedef uint64_t ClockSize;
\r
110 //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
\r
111 SYS_TIMEBASE_GET( newTime );
\r
112 m_data->mStartTime = newTime;
\r
114 gettimeofday(&m_data->mStartTime, 0);
\r
119 /// Returns the time in ms since the last call to reset or since
\r
120 /// the btStopwatch was created.
\r
121 float btStopwatch::getTimeMilliseconds()
\r
123 return getTimeMicroseconds()/1000.f;
\r
126 /// Returns the time in us since the last call to reset or since
\r
127 /// the stopwatch was created.
\r
128 unsigned long int btStopwatch::getTimeMicroseconds()
\r
130 #ifdef BT_USE_WINDOWS_TIMERS
\r
131 LARGE_INTEGER currentTime;
\r
132 QueryPerformanceCounter(¤tTime);
\r
133 LONGLONG elapsedTime = currentTime.QuadPart - m_data->mStartTime.QuadPart;
\r
135 // Compute the number of millisecond ticks elapsed.
\r
136 unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / m_data->mClockFrequency.QuadPart);
\r
138 // Check for unexpected leaps in the Win32 performance counter.
\r
139 // (This is caused by unexpected data across the PCI to ISA
\r
140 // bridge, aka south bridge. See Microsoft KB274323.)
\r
141 unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick;
\r
142 signed long msecOff = (signed long)(msecTicks - elapsedTicks);
\r
143 if (msecOff < -100 || msecOff > 100)
\r
145 // Adjust the starting time forwards.
\r
146 LONGLONG msecAdjustment = mymin(msecOff *
\r
147 m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
\r
148 m_data->mPrevElapsedTime);
\r
149 m_data->mStartTime.QuadPart += msecAdjustment;
\r
150 elapsedTime -= msecAdjustment;
\r
153 // Store the current elapsed time for adjustments next time.
\r
154 m_data->mPrevElapsedTime = elapsedTime;
\r
156 // Convert to microseconds.
\r
157 unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime /
\r
158 m_data->mClockFrequency.QuadPart);
\r
163 #ifdef __CELLOS_LV2__
\r
164 uint64_t freq=sys_time_get_timebase_frequency();
\r
165 double dFreq=((double) freq)/ 1000000.0;
\r
166 typedef uint64_t ClockSize;
\r
168 //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
\r
169 SYS_TIMEBASE_GET( newTime );
\r
171 return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
\r
174 struct timeval currentTime;
\r
175 gettimeofday(¤tTime, 0);
\r
176 return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + (currentTime.tv_usec - m_data->mStartTime.tv_usec);
\r
177 #endif//__CELLOS_LV2__
\r