mark a. foltz | c28ca40 | 2018-07-19 16:11:32 -0700 | [diff] [blame] | 1 | // 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 Wiitala | eb8eee7 | 2019-03-26 15:52:43 -0700 | [diff] [blame] | 8 | #include <chrono> |
Ryan Keane | efab2ed | 2019-07-22 12:36:53 -0700 | [diff] [blame] | 9 | #include <ostream> |
mark a. foltz | c28ca40 | 2018-07-19 16:11:32 -0700 | [diff] [blame] | 10 | |
| 11 | namespace openscreen { |
| 12 | namespace platform { |
| 13 | |
Yuri Wiitala | eb8eee7 | 2019-03-26 15:52:43 -0700 | [diff] [blame] | 14 | // For proper behavior of the OpenScreen library, the Clock implementation must |
| 15 | // tick at least 10000 times per second. |
| 16 | using 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). |
| 23 | class Clock { |
btolsch | 5292c94 | 2018-07-26 00:06:22 -0700 | [diff] [blame] | 24 | public: |
Yuri Wiitala | eb8eee7 | 2019-03-26 15:52:43 -0700 | [diff] [blame] | 25 | // 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. foltz | c28ca40 | 2018-07-19 16:11:32 -0700 | [diff] [blame] | 31 | |
Yuri Wiitala | eb8eee7 | 2019-03-26 15:52:43 -0700 | [diff] [blame] | 32 | static time_point now() noexcept; |
btolsch | 5292c94 | 2018-07-26 00:06:22 -0700 | [diff] [blame] | 33 | |
Yuri Wiitala | eb8eee7 | 2019-03-26 15:52:43 -0700 | [diff] [blame] | 34 | // 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; |
btolsch | c11dc34 | 2019-01-16 16:37:34 -0800 | [diff] [blame] | 38 | |
Yuri Wiitala | eb8eee7 | 2019-03-26 15:52:43 -0700 | [diff] [blame] | 39 | // "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"); |
btolsch | 5292c94 | 2018-07-26 00:06:22 -0700 | [diff] [blame] | 44 | }; |
| 45 | |
Ryan Keane | efab2ed | 2019-07-22 12:36:53 -0700 | [diff] [blame] | 46 | inline 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 Wiitala | eb8eee7 | 2019-03-26 15:52:43 -0700 | [diff] [blame] | 51 | // 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). |
| 54 | using 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. |
| 60 | std::chrono::seconds GetWallTimeSinceUnixEpoch() noexcept; |
mark a. foltz | c28ca40 | 2018-07-19 16:11:32 -0700 | [diff] [blame] | 61 | |
| 62 | } // namespace platform |
| 63 | } // namespace openscreen |
| 64 | |
btolsch | a21e8ed | 2018-08-30 15:13:48 -0700 | [diff] [blame] | 65 | #endif // PLATFORM_API_TIME_H_ |