blob: 979d649c9d56a268a4dac6c86c6b30f1081de92e [file] [log] [blame]
mark a. foltzc28ca402018-07-19 16:11:32 -07001// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef PLATFORM_API_TIME_H_
6#define PLATFORM_API_TIME_H_
7
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -07008#include <chrono>
Ryan Keaneefab2ed2019-07-22 12:36:53 -07009#include <ostream>
mark a. foltzc28ca402018-07-19 16:11:32 -070010
11namespace openscreen {
12namespace platform {
13
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070014// For proper behavior of the OpenScreen library, the Clock implementation must
15// tick at least 10000 times per second.
16using kRequiredClockResolution = std::ratio<1, 10000>;
17
18// A monotonic clock that meets all the C++14 requirements of a TrivialClock,
19// for use with the chrono library. The default platform implementation bases
20// this on std::chrono::steady_clock or std::chrono::high_resolution_clock, but
21// a custom implementation may use a different source of time (e.g., an
22// embedder's time library, a simulated time source, or a mock).
23class Clock {
btolsch5292c942018-07-26 00:06:22 -070024 public:
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070025 // TrivialClock named requirements: std::chrono templates can/may use these.
26 using duration = std::chrono::microseconds;
27 using rep = duration::rep;
28 using period = duration::period;
29 using time_point = std::chrono::time_point<Clock, duration>;
30 static constexpr bool is_steady = true;
mark a. foltzc28ca402018-07-19 16:11:32 -070031
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070032 static time_point now() noexcept;
btolsch5292c942018-07-26 00:06:22 -070033
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070034 // In <chrono>, a Clock is just some type properties plus a static now()
35 // function. So, there's nothing to instantiate here.
36 Clock() = delete;
37 ~Clock() = delete;
btolschc11dc342019-01-16 16:37:34 -080038
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070039 // "Trivially copyable" is necessary for use in std::atomic<>.
40 static_assert(std::is_trivially_copyable<duration>(),
41 "duration is not trivially copyable");
42 static_assert(std::is_trivially_copyable<time_point>(),
43 "time_point is not trivially copyable");
btolsch5292c942018-07-26 00:06:22 -070044};
45
Ryan Keaneefab2ed2019-07-22 12:36:53 -070046inline std::ostream& operator<<(std::ostream& os, const Clock::time_point& tp) {
47 constexpr auto microseconds_symbol = "\u03BCs"; // Greek Mu + 's'
48 return os << tp.time_since_epoch().count() << microseconds_symbol;
49}
50
Yuri Wiitalaeb8eee72019-03-26 15:52:43 -070051// Convenience, for injecting Clocks into classes. Note: The 'noexcept' keyword
52// is dropped here to avoid a well-known Clang compiler warning (about an
53// upcoming C++20 ABI change).
54using ClockNowFunctionPtr = Clock::time_point (*)();
55
56// Returns the number of seconds since UNIX epoch (1 Jan 1970, midnight)
57// according to the wall clock, which is subject to adjustments (e.g., via
58// NTP). Note that this is NOT the same time source as Clock::now() above, and
59// is NOT guaranteed to be monotonically non-decreasing.
60std::chrono::seconds GetWallTimeSinceUnixEpoch() noexcept;
mark a. foltzc28ca402018-07-19 16:11:32 -070061
62} // namespace platform
63} // namespace openscreen
64
btolscha21e8ed2018-08-30 15:13:48 -070065#endif // PLATFORM_API_TIME_H_