xref: /aosp_15_r20/external/webrtc/system_wrappers/source/clock.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2013 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 
11 #include "system_wrappers/include/clock.h"
12 
13 #include "rtc_base/time_utils.h"
14 
15 namespace webrtc {
16 namespace {
17 
NtpOffsetUsCalledOnce()18 int64_t NtpOffsetUsCalledOnce() {
19   constexpr int64_t kNtpJan1970Sec = 2208988800;
20   int64_t clock_time = rtc::TimeMicros();
21   int64_t utc_time = rtc::TimeUTCMicros();
22   return utc_time - clock_time + kNtpJan1970Sec * rtc::kNumMicrosecsPerSec;
23 }
24 
TimeMicrosToNtp(int64_t time_us)25 NtpTime TimeMicrosToNtp(int64_t time_us) {
26   static int64_t ntp_offset_us = NtpOffsetUsCalledOnce();
27 
28   int64_t time_ntp_us = time_us + ntp_offset_us;
29   RTC_DCHECK_GE(time_ntp_us, 0);  // Time before year 1900 is unsupported.
30 
31   // Convert seconds to uint32 through uint64 for a well-defined cast.
32   // A wrap around, which will happen in 2036, is expected for NTP time.
33   uint32_t ntp_seconds =
34       static_cast<uint64_t>(time_ntp_us / rtc::kNumMicrosecsPerSec);
35 
36   // Scale fractions of the second to NTP resolution.
37   constexpr int64_t kNtpFractionsInSecond = 1LL << 32;
38   int64_t us_fractions = time_ntp_us % rtc::kNumMicrosecsPerSec;
39   uint32_t ntp_fractions =
40       us_fractions * kNtpFractionsInSecond / rtc::kNumMicrosecsPerSec;
41 
42   return NtpTime(ntp_seconds, ntp_fractions);
43 }
44 
45 }  // namespace
46 
47 class RealTimeClock : public Clock {
48  public:
49   RealTimeClock() = default;
50 
CurrentTime()51   Timestamp CurrentTime() override {
52     return Timestamp::Micros(rtc::TimeMicros());
53   }
54 
ConvertTimestampToNtpTime(Timestamp timestamp)55   NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) override {
56     return TimeMicrosToNtp(timestamp.us());
57   }
58 };
59 
GetRealTimeClock()60 Clock* Clock::GetRealTimeClock() {
61   static Clock* const clock = new RealTimeClock();
62   return clock;
63 }
64 
SimulatedClock(int64_t initial_time_us)65 SimulatedClock::SimulatedClock(int64_t initial_time_us)
66     : time_us_(initial_time_us) {}
67 
SimulatedClock(Timestamp initial_time)68 SimulatedClock::SimulatedClock(Timestamp initial_time)
69     : SimulatedClock(initial_time.us()) {}
70 
~SimulatedClock()71 SimulatedClock::~SimulatedClock() {}
72 
CurrentTime()73 Timestamp SimulatedClock::CurrentTime() {
74   return Timestamp::Micros(time_us_.load(std::memory_order_relaxed));
75 }
76 
ConvertTimestampToNtpTime(Timestamp timestamp)77 NtpTime SimulatedClock::ConvertTimestampToNtpTime(Timestamp timestamp) {
78   int64_t now_us = timestamp.us();
79   uint32_t seconds = (now_us / 1'000'000) + kNtpJan1970;
80   uint32_t fractions = static_cast<uint32_t>(
81       (now_us % 1'000'000) * kMagicNtpFractionalUnit / 1'000'000);
82   return NtpTime(seconds, fractions);
83 }
84 
AdvanceTimeMilliseconds(int64_t milliseconds)85 void SimulatedClock::AdvanceTimeMilliseconds(int64_t milliseconds) {
86   AdvanceTime(TimeDelta::Millis(milliseconds));
87 }
88 
AdvanceTimeMicroseconds(int64_t microseconds)89 void SimulatedClock::AdvanceTimeMicroseconds(int64_t microseconds) {
90   AdvanceTime(TimeDelta::Micros(microseconds));
91 }
92 
93 // TODO(bugs.webrtc.org(12102): It's desirable to let a single thread own
94 // advancement of the clock. We could then replace this read-modify-write
95 // operation with just a thread checker. But currently, that breaks a couple of
96 // tests, in particular, RepeatingTaskTest.ClockIntegration and
97 // CallStatsTest.LastProcessedRtt.
AdvanceTime(TimeDelta delta)98 void SimulatedClock::AdvanceTime(TimeDelta delta) {
99   time_us_.fetch_add(delta.us(), std::memory_order_relaxed);
100 }
101 
102 }  // namespace webrtc
103