blob: bc8fcfe91b3f90b22fa9283ab77c79893cbf1528 [file] [log] [blame]
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Henrik Kjellander98f53512015-10-28 18:17:40 +010011#include "webrtc/system_wrappers/include/tick_util.h"
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <assert.h>
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000014
15namespace webrtc {
16
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000017bool TickTime::use_fake_clock_ = false;
pbos@webrtc.org046deb92013-04-09 09:06:11 +000018int64_t TickTime::fake_ticks_ = 0;
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000019
pbos@webrtc.org046deb92013-04-09 09:06:11 +000020void TickTime::UseFakeClock(int64_t start_millisecond) {
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000021 use_fake_clock_ = true;
22 fake_ticks_ = MillisecondsToTicks(start_millisecond);
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000023}
24
pbos@webrtc.org046deb92013-04-09 09:06:11 +000025void TickTime::AdvanceFakeClock(int64_t milliseconds) {
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000026 assert(use_fake_clock_);
27 fake_ticks_ += MillisecondsToTicks(milliseconds);
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000028}
29
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000030int64_t TickTime::QueryOsForTicks() {
thalounc91d1732015-11-16 16:28:49 -080031 TickTime result;
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000032#if _WIN32
thalounc91d1732015-11-16 16:28:49 -080033 // TODO(wu): Remove QueryPerformanceCounter implementation.
34#ifdef USE_QUERY_PERFORMANCE_COUNTER
35 // QueryPerformanceCounter returns the value from the TSC which is
36 // incremented at the CPU frequency. The algorithm used requires
37 // the CPU frequency to be constant. Technology like speed stepping
38 // which has variable CPU frequency will therefore yield unpredictable,
39 // incorrect time estimations.
40 LARGE_INTEGER qpcnt;
41 QueryPerformanceCounter(&qpcnt);
42 result.ticks_ = qpcnt.QuadPart;
43#else
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000044 static volatile LONG last_time_get_time = 0;
45 static volatile int64_t num_wrap_time_get_time = 0;
46 volatile LONG* last_time_get_time_ptr = &last_time_get_time;
47 DWORD now = timeGetTime();
48 // Atomically update the last gotten time
49 DWORD old = InterlockedExchange(last_time_get_time_ptr, now);
50 if (now < old) {
51 // If now is earlier than old, there may have been a race between
52 // threads.
53 // 0x0fffffff ~3.1 days, the code will not take that long to execute
54 // so it must have been a wrap around.
55 if (old > 0xf0000000 && now < 0x0fffffff) {
56 num_wrap_time_get_time++;
57 }
58 }
thalounc91d1732015-11-16 16:28:49 -080059 result.ticks_ = now + (num_wrap_time_get_time << 32);
60#endif
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000061#elif defined(WEBRTC_LINUX)
62 struct timespec ts;
63 // TODO(wu): Remove CLOCK_REALTIME implementation.
64#ifdef WEBRTC_CLOCK_TYPE_REALTIME
65 clock_gettime(CLOCK_REALTIME, &ts);
66#else
67 clock_gettime(CLOCK_MONOTONIC, &ts);
68#endif
thalounc91d1732015-11-16 16:28:49 -080069 result.ticks_ = 1000000000LL * static_cast<int64_t>(ts.tv_sec) +
70 static_cast<int64_t>(ts.tv_nsec);
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000071#elif defined(WEBRTC_MAC)
thalounc91d1732015-11-16 16:28:49 -080072 static mach_timebase_info_data_t timebase;
73 if (timebase.denom == 0) {
74 // Get the timebase if this is the first time we run.
75 // Recommended by Apple's QA1398.
76 kern_return_t retval = mach_timebase_info(&timebase);
77 if (retval != KERN_SUCCESS) {
78 // TODO(wu): Implement RTC_CHECK for all the platforms. Then replace this
79 // with a RTC_CHECK_EQ(retval, KERN_SUCCESS);
80#ifndef WEBRTC_IOS
81 asm("int3");
82#else
83 __builtin_trap();
84#endif // WEBRTC_IOS
85 }
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000086 }
thalounc91d1732015-11-16 16:28:49 -080087 // Use timebase to convert absolute time tick units into nanoseconds.
88 result.ticks_ = mach_absolute_time() * timebase.numer / timebase.denom;
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000089#else
90 struct timeval tv;
91 gettimeofday(&tv, NULL);
thalounc91d1732015-11-16 16:28:49 -080092 result.ticks_ = 1000000LL * static_cast<int64_t>(tv.tv_sec) +
93 static_cast<int64_t>(tv.tv_usec);
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000094#endif
thalounc91d1732015-11-16 16:28:49 -080095 return result.ticks_;
fischman@webrtc.org1d4a2d52013-06-27 17:15:20 +000096}
97
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000098} // namespace webrtc