b3Clock.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "b3Clock.h"
  2. template <class T>
  3. const T& b3ClockMin(const T& a, const T& b)
  4. {
  5. return a < b ? a : b;
  6. }
  7. #ifdef __CELLOS_LV2__
  8. #include <sys/sys_time.h>
  9. #include <sys/time_util.h>
  10. #include <stdio.h>
  11. #endif
  12. #if defined(SUNOS) || defined(__SUNOS__)
  13. #include <stdio.h>
  14. #endif
  15. #if defined(WIN32) || defined(_WIN32)
  16. #define B3_USE_WINDOWS_TIMERS
  17. #define WIN32_LEAN_AND_MEAN
  18. #define NOWINRES
  19. #define NOMCX
  20. #define NOIME
  21. #ifdef _XBOX
  22. #include <Xtl.h>
  23. #else //_XBOX
  24. #include <windows.h>
  25. #endif //_XBOX
  26. #include <time.h>
  27. #else //_WIN32
  28. #include <sys/time.h>
  29. #include <unistd.h>
  30. #endif //_WIN32
  31. struct b3ClockData
  32. {
  33. #ifdef B3_USE_WINDOWS_TIMERS
  34. LARGE_INTEGER mClockFrequency;
  35. LARGE_INTEGER mStartTime;
  36. #else
  37. #ifdef __CELLOS_LV2__
  38. uint64_t mStartTime;
  39. #else
  40. struct timeval mStartTime;
  41. #endif
  42. #endif //__CELLOS_LV2__
  43. };
  44. ///The b3Clock is a portable basic clock that measures accurate time in seconds, use for profiling.
  45. b3Clock::b3Clock()
  46. {
  47. m_data = new b3ClockData;
  48. #ifdef B3_USE_WINDOWS_TIMERS
  49. QueryPerformanceFrequency(&m_data->mClockFrequency);
  50. #endif
  51. reset();
  52. }
  53. b3Clock::~b3Clock()
  54. {
  55. delete m_data;
  56. }
  57. b3Clock::b3Clock(const b3Clock& other)
  58. {
  59. m_data = new b3ClockData;
  60. *m_data = *other.m_data;
  61. }
  62. b3Clock& b3Clock::operator=(const b3Clock& other)
  63. {
  64. *m_data = *other.m_data;
  65. return *this;
  66. }
  67. /// Resets the initial reference time.
  68. void b3Clock::reset(bool zeroReference)
  69. {
  70. if (zeroReference)
  71. {
  72. #ifdef B3_USE_WINDOWS_TIMERS
  73. m_data->mStartTime.QuadPart = 0;
  74. #else
  75. #ifdef __CELLOS_LV2__
  76. m_data->mStartTime = 0;
  77. #else
  78. m_data->mStartTime = (struct timeval){0};
  79. #endif
  80. #endif
  81. }
  82. else
  83. {
  84. #ifdef B3_USE_WINDOWS_TIMERS
  85. QueryPerformanceCounter(&m_data->mStartTime);
  86. #else
  87. #ifdef __CELLOS_LV2__
  88. typedef uint64_t ClockSize;
  89. ClockSize newTime;
  90. //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
  91. SYS_TIMEBASE_GET(newTime);
  92. m_data->mStartTime = newTime;
  93. #else
  94. gettimeofday(&m_data->mStartTime, 0);
  95. #endif
  96. #endif
  97. }
  98. }
  99. /// Returns the time in ms since the last call to reset or since
  100. /// the b3Clock was created.
  101. unsigned long int b3Clock::getTimeMilliseconds()
  102. {
  103. #ifdef B3_USE_WINDOWS_TIMERS
  104. LARGE_INTEGER currentTime;
  105. QueryPerformanceCounter(&currentTime);
  106. LONGLONG elapsedTime = currentTime.QuadPart -
  107. m_data->mStartTime.QuadPart;
  108. // Compute the number of millisecond ticks elapsed.
  109. unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
  110. m_data->mClockFrequency.QuadPart);
  111. return msecTicks;
  112. #else
  113. #ifdef __CELLOS_LV2__
  114. uint64_t freq = sys_time_get_timebase_frequency();
  115. double dFreq = ((double)freq) / 1000.0;
  116. typedef uint64_t ClockSize;
  117. ClockSize newTime;
  118. SYS_TIMEBASE_GET(newTime);
  119. //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
  120. return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq);
  121. #else
  122. struct timeval currentTime;
  123. gettimeofday(&currentTime, 0);
  124. return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 +
  125. (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000;
  126. #endif //__CELLOS_LV2__
  127. #endif
  128. }
  129. /// Returns the time in us since the last call to reset or since
  130. /// the Clock was created.
  131. unsigned long long int b3Clock::getTimeMicroseconds()
  132. {
  133. #ifdef B3_USE_WINDOWS_TIMERS
  134. //see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
  135. LARGE_INTEGER currentTime, elapsedTime;
  136. QueryPerformanceCounter(&currentTime);
  137. elapsedTime.QuadPart = currentTime.QuadPart -
  138. m_data->mStartTime.QuadPart;
  139. elapsedTime.QuadPart *= 1000000;
  140. elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
  141. return (unsigned long long)elapsedTime.QuadPart;
  142. #else
  143. #ifdef __CELLOS_LV2__
  144. uint64_t freq = sys_time_get_timebase_frequency();
  145. double dFreq = ((double)freq) / 1000000.0;
  146. typedef uint64_t ClockSize;
  147. ClockSize newTime;
  148. //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
  149. SYS_TIMEBASE_GET(newTime);
  150. return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq);
  151. #else
  152. struct timeval currentTime;
  153. gettimeofday(&currentTime, 0);
  154. return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 +
  155. (currentTime.tv_usec - m_data->mStartTime.tv_usec);
  156. #endif //__CELLOS_LV2__
  157. #endif
  158. }
  159. double b3Clock::getTimeInSeconds()
  160. {
  161. return double(getTimeMicroseconds() / 1.e6);
  162. }
  163. void b3Clock::usleep(int microSeconds)
  164. {
  165. #ifdef _WIN32
  166. if (microSeconds == 0)
  167. {
  168. Sleep(0);
  169. }
  170. else
  171. {
  172. int millis = microSeconds / 1000;
  173. if (millis < 1)
  174. millis = 1;
  175. Sleep(millis);
  176. }
  177. #else
  178. if (microSeconds > 0)
  179. {
  180. ::usleep(microSeconds);
  181. //struct timeval tv;
  182. //tv.tv_sec = microSeconds/1000000L;
  183. //tv.tv_usec = microSeconds%1000000L;
  184. //return select(0, 0, 0, 0, &tv);
  185. }
  186. #endif
  187. }