12 #if defined(AJA_COLLECT_SLEEP_STATS)
17 #endif // defined(AJA_COLLECT_SLEEP_STATS)
20 #include <mach/mach_time.h>
21 #include <CoreServices/CoreServices.h>
22 static int64_t s_PerformanceFrequency;
23 static bool s_bPerformanceInit =
false;
25 #if defined(AJA_SLEEP_USE_STL) || defined(AJA_SYSCLK_USE_STL)
28 #endif // AJA_SLEEP_USE_STL || AJA_SYSCLK_USE_STL
30 #if defined(AJA_WINDOWS)
32 static LARGE_INTEGER s_PerformanceFrequency;
33 static bool s_bPerformanceInit =
false;
36 #if defined(_MSC_VER) && defined(_M_X64)
39 static inline uint64_t util_mul_div64(uint64_t num, uint64_t mul, uint64_t div)
41 #if defined(_MSC_VER) && defined(_M_X64) && (_MSC_VER >= 1920)
42 unsigned __int64 high;
43 const unsigned __int64 low = _umul128(num, mul, &high);
45 return _udiv128(high, low, div, &rem);
47 const uint64_t rem = num % div;
48 return (num / div) * mul + (rem * mul) / div;
52 #elif defined(AJA_LINUX)
54 #if (_POSIX_TIMERS > 0)
55 #ifdef _POSIX_MONOTONIC_CLOCK
56 #define AJA_USE_CLOCK_GETTIME
58 #undef AJA_USE_CLOCK_GETTIME
62 #ifdef AJA_USE_CLOCK_GETTIME
69 #elif defined(AJA_BAREMETAL)
77 #if defined(AJA_SYSCLK_USE_STL)
79 #elif defined(AJA_WINDOWS)
80 return (int64_t)::timeGetTime();
81 #elif defined(AJA_MAC)
82 static mach_timebase_info_data_t sTimebaseInfo;
83 uint64_t ticks = ::mach_absolute_time();
85 if ( sTimebaseInfo.denom == 0 )
87 (
void) mach_timebase_info(&sTimebaseInfo);
92 int64_t nanoSeconds = ticks * sTimebaseInfo.numer / sTimebaseInfo.denom;
94 #elif defined(AJA_LINUX)
95 #ifdef AJA_USE_CLOCK_GETTIME
98 return (ts.tv_sec * ((int64_t)1000)) + (ts.tv_nsec / (int64_t)1000000);
103 gettimeofday( &tv, &tz );
104 return (int64_t)((tv.tv_sec * ((int64_t)1000)) + (int64_t)(tv.tv_usec / 1000));
114 #if defined(AJA_SYSCLK_USE_STL)
116 #elif defined(AJA_WINDOWS)
117 LARGE_INTEGER performanceCounter;
119 performanceCounter.QuadPart = 0;
120 if (!QueryPerformanceCounter(&performanceCounter))
125 return (int64_t)performanceCounter.QuadPart;
126 #elif defined(AJA_MAC)
130 return int64_t(mach_absolute_time());
131 #elif defined(AJA_LINUX)
132 #ifdef AJA_USE_CLOCK_GETTIME
135 return (ts.tv_sec * ((int64_t)1000000000)) + (ts.tv_nsec);
140 gettimeofday( &tv, &tz );
141 return (int64_t)((int64_t)tv.tv_sec * (int64_t)1000000 + tv.tv_usec);
151 #if defined(AJA_SYSCLK_USE_STL)
153 #elif defined(AJA_WINDOWS)
154 if (!s_bPerformanceInit)
156 QueryPerformanceFrequency(&s_PerformanceFrequency);
157 s_bPerformanceInit =
true;
159 return (int64_t)s_PerformanceFrequency.QuadPart;
160 #elif defined(AJA_MAC)
161 if (!s_bPerformanceInit)
164 static mach_timebase_info_data_t sTimebaseInfo;
165 uint64_t ticks = 1000000000;
167 if ( sTimebaseInfo.denom == 0 )
169 (
void) mach_timebase_info(&sTimebaseInfo);
174 int64_t nanoSeconds = ticks * sTimebaseInfo.numer / sTimebaseInfo.denom;
177 s_PerformanceFrequency = ticks * 1000000000 / nanoSeconds;
178 s_bPerformanceInit =
true;
180 return s_PerformanceFrequency;
181 #elif defined(AJA_LINUX)
182 #ifdef AJA_USE_CLOCK_GETTIME
200 sec = ticks / ticksPerSecond;
215 ms = uint64_t((
double(ticks) /
double(ticksPerSecond)) * 1000.);
230 us = uint64_t((
double(ticks) /
double(ticksPerSecond)) * 1000000.);
245 us = uint64_t((
double(ticks) /
double(ticksPerSecond)) * 1000000000.);
251 #if defined(AJA_COLLECT_SLEEP_STATS)
252 static uint64_t sMonThreadID = 0;
253 static const double sPercentiles[] = { 1.0, 1.1, 1.2, 1.5, 2.0, 3.0, 6.0, 11.0, 21.0, 51.0, 101.0, 201.0, 501.0, 1001.0, 2001.0, 5001.0, 10001.0};
254 static uint32_t sCounts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
255 static int sNumPercentiles =
sizeof(sPercentiles) /
sizeof(
double);
256 static int sNumCounts =
sizeof(sCounts) /
sizeof(uint32_t);
259 #define PRE_STATS const bool doStats(sMonThreadID == AJAThread::GetThreadId()); \
265 #define POST_STATS(_req_) if (doStats) \
267 const double act(sTimer.ETSecs()); \
268 const double req(_req_); \
269 for (int n(0); n < sNumPercentiles; n++) \
270 if (act < (sPercentiles[n] * req)) \
272 AJAAtomic::Increment(&sCounts[n]); \
275 AJAAtomic::Increment(&sCounts[sNumPercentiles]); \
277 #else // AJA_COLLECT_SLEEP_STATS
279 #define POST_STATS(__x__)
280 #endif // !defined(AJA_COLLECT_SLEEP_STATS)
290 #if defined(AJA_SLEEP_USE_STL)
291 std::this_thread::sleep_for(std::chrono::milliseconds(inTime));
292 #elif defined(AJA_WINDOWS)
294 #elif defined(AJA_BAREMETAL)
295 usleep(inTime * 1000);
297 usleep(inTime * 1000);
310 #if defined(AJA_SLEEP_USE_STL)
311 std::this_thread::sleep_for(std::chrono::microseconds(inTime));
312 #elif defined(AJA_WINDOWS)
314 #elif defined(AJA_BAREMETAL)
328 #if defined(AJA_SLEEP_USE_STL)
329 std::this_thread::sleep_for(std::chrono::nanoseconds(inTime));
330 #elif defined(AJA_WINDOWS)
334 const LONGLONG countTarget = (LONGLONG)util_mul_div64(timeTarget, freq, 1000000000);
336 const bool stall = count < countTarget;
338 DWORD milliseconds = (DWORD)(((countTarget - count) * 1000.0) / freq);
339 if (milliseconds > 1) {
340 Sleep(milliseconds - 1);
344 if (count >= countTarget)
349 #elif defined(AJA_BAREMETAL)
353 req.tv_sec = inTime / 1000000000;
354 req.tv_nsec = long(inTime) % 1000000000L;
357 nanosleep(&req, &rm);
364 #if defined(AJA_COLLECT_SLEEP_STATS)
365 bool AJATime::CollectSleepStats (
const bool inEnable)
368 {sMonThreadID = 0;
return true;}
371 for (
int n(0); n < sNumPercentiles; n++)
377 std::string AJATime::GetSleepStats (
void)
379 std::ostringstream oss;
380 for (
int n(0); n < sNumCounts; n++)
383 oss << sCounts[n] <<
"\t< " << sPercentiles[n] << std::endl;
387 #endif // defined(AJA_COLLECT_SLEEP_STATS)