diff options
Diffstat (limited to 'third_party/libwebrtc/system_wrappers/source/clock.cc')
-rw-r--r-- | third_party/libwebrtc/system_wrappers/source/clock.cc | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/third_party/libwebrtc/system_wrappers/source/clock.cc b/third_party/libwebrtc/system_wrappers/source/clock.cc new file mode 100644 index 0000000000..f7460b831c --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/source/clock.cc @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "system_wrappers/include/clock.h" + +#include "rtc_base/time_utils.h" + +namespace webrtc { +namespace { + +int64_t NtpOffsetUsCalledOnce() { + constexpr int64_t kNtpJan1970Sec = 2208988800; + int64_t clock_time = rtc::TimeMicros(); + int64_t utc_time = rtc::TimeUTCMicros(); + return utc_time - clock_time + kNtpJan1970Sec * rtc::kNumMicrosecsPerSec; +} + +NtpTime TimeMicrosToNtp(int64_t time_us) { + static int64_t ntp_offset_us = NtpOffsetUsCalledOnce(); + + int64_t time_ntp_us = time_us + ntp_offset_us; + RTC_DCHECK_GE(time_ntp_us, 0); // Time before year 1900 is unsupported. + + // Convert seconds to uint32 through uint64 for a well-defined cast. + // A wrap around, which will happen in 2036, is expected for NTP time. + uint32_t ntp_seconds = + static_cast<uint64_t>(time_ntp_us / rtc::kNumMicrosecsPerSec); + + // Scale fractions of the second to NTP resolution. + constexpr int64_t kNtpFractionsInSecond = 1LL << 32; + int64_t us_fractions = time_ntp_us % rtc::kNumMicrosecsPerSec; + uint32_t ntp_fractions = + us_fractions * kNtpFractionsInSecond / rtc::kNumMicrosecsPerSec; + + return NtpTime(ntp_seconds, ntp_fractions); +} + +} // namespace + +class RealTimeClock : public Clock { + public: + RealTimeClock() = default; + + Timestamp CurrentTime() override { + return Timestamp::Micros(rtc::TimeMicros()); + } + + NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) override { + return TimeMicrosToNtp(timestamp.us()); + } +}; + +Clock* Clock::GetRealTimeClockRaw() { + static Clock* const clock = new RealTimeClock(); + return clock; +} + +SimulatedClock::SimulatedClock(int64_t initial_time_us) + : time_us_(initial_time_us) {} + +SimulatedClock::SimulatedClock(Timestamp initial_time) + : SimulatedClock(initial_time.us()) {} + +SimulatedClock::~SimulatedClock() {} + +Timestamp SimulatedClock::CurrentTime() { + return Timestamp::Micros(time_us_.load(std::memory_order_relaxed)); +} + +NtpTime SimulatedClock::ConvertTimestampToNtpTime(Timestamp timestamp) { + int64_t now_us = timestamp.us(); + uint32_t seconds = (now_us / 1'000'000) + kNtpJan1970; + uint32_t fractions = static_cast<uint32_t>( + (now_us % 1'000'000) * kMagicNtpFractionalUnit / 1'000'000); + return NtpTime(seconds, fractions); +} + +void SimulatedClock::AdvanceTimeMilliseconds(int64_t milliseconds) { + AdvanceTime(TimeDelta::Millis(milliseconds)); +} + +void SimulatedClock::AdvanceTimeMicroseconds(int64_t microseconds) { + AdvanceTime(TimeDelta::Micros(microseconds)); +} + +// TODO(bugs.webrtc.org(12102): It's desirable to let a single thread own +// advancement of the clock. We could then replace this read-modify-write +// operation with just a thread checker. But currently, that breaks a couple of +// tests, in particular, RepeatingTaskTest.ClockIntegration and +// CallStatsTest.LastProcessedRtt. +void SimulatedClock::AdvanceTime(TimeDelta delta) { + time_us_.fetch_add(delta.us(), std::memory_order_relaxed); +} + +} // namespace webrtc |