1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #pragma once
9 
10 #include <chrono>
11 #include <type_traits>
12 
13 namespace ABI48_0_0facebook {
14 namespace ABI48_0_0React {
15 
16 /*
17  * Represents a monotonic clock suitable for measuring intervals.
18  */
19 using TelemetryClock = std::chrono::steady_clock;
20 
21 /*
22  * Represents a point in time satisfied the requirements of TelemetryClock.
23  */
24 using TelemetryTimePoint = TelemetryClock::time_point;
25 
26 /*
27  * Represents a time interval satisfied the requirements of TelemetryClock.
28  */
29 using TelemetryDuration = std::chrono::nanoseconds;
30 
31 /*
32  * Represents a time point which never happens.
33  */
34 static TelemetryTimePoint const kTelemetryUndefinedTimePoint =
35     TelemetryTimePoint::max();
36 
37 /*
38  * Returns a time point representing the current point in time.
39  */
telemetryTimePointNow()40 static inline TelemetryTimePoint telemetryTimePointNow() {
41   return TelemetryClock::now();
42 }
43 
44 /*
45  * Returns a number of milliseconds that passed from some epoch starting time
46  * point to a given time point. The epoch starting time point is not specified
47  * but stays the same for an application run.
48  */
telemetryTimePointToMilliseconds(TelemetryTimePoint timePoint)49 static inline int64_t telemetryTimePointToMilliseconds(
50     TelemetryTimePoint timePoint) {
51   return std::chrono::duration_cast<std::chrono::milliseconds>(
52              timePoint - TelemetryTimePoint{})
53       .count();
54 }
55 
56 /*
57  * Returns a number of seconds that passed from "Steady Clock" epoch starting
58  * time point to a given time point.
59  */
telemetryTimePointToSteadyClockSeconds(TelemetryTimePoint timePoint)60 static inline double telemetryTimePointToSteadyClockSeconds(
61     TelemetryTimePoint timePoint) {
62   static_assert(
63       std::is_same<decltype(timePoint), std::chrono::steady_clock::time_point>::
64           value,
65       "`TelemetryClock` must be `std::chrono::steady_clock` to make the "
66       "following implementation work correctly.");
67 
68   auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
69                          timePoint.time_since_epoch())
70                          .count();
71   return (double)nanoseconds / 1.0e9;
72 }
73 
74 /*
75  * Converts a time point on one clock to a time point on a different clock.
76  */
77 template <
78     typename DestinationTimePointT,
79     typename SourceTimePointT,
80     typename DestnationClockT = typename DestinationTimePointT::clock,
81     typename SourceClockT = typename SourceTimePointT::clock>
clockCast(SourceTimePointT timePoint)82 DestinationTimePointT clockCast(SourceTimePointT timePoint) {
83   auto sourseClockNow = SourceClockT::now();
84   auto destinationClockNow = DestnationClockT::now();
85   return std::chrono::time_point_cast<typename DestnationClockT::duration>(
86       timePoint - sourseClockNow + destinationClockNow);
87 }
88 
89 /*
90  * Returns a number of seconds that passed from the UNIX Epoch starting time
91  * point to a given time point.
92  * Also known as POSIX time or UNIX Timestamp.
93  */
telemetryTimePointToSecondsSinceEpoch(TelemetryTimePoint timePoint)94 static inline double telemetryTimePointToSecondsSinceEpoch(
95     TelemetryTimePoint timePoint) {
96   auto systemClockTimePoint =
97       clockCast<std::chrono::system_clock::time_point, TelemetryTimePoint>(
98           timePoint);
99   return (double)std::chrono::duration_cast<std::chrono::microseconds>(
100              systemClockTimePoint.time_since_epoch())
101              .count() /
102       1000000.0;
103 }
104 
105 /*
106  * Returns a number of milliseconds that represents the given duration object.
107  */
telemetryDurationToMilliseconds(TelemetryDuration duration)108 static inline int64_t telemetryDurationToMilliseconds(
109     TelemetryDuration duration) {
110   return std::chrono::duration_cast<std::chrono::milliseconds>(duration)
111       .count();
112 }
113 
114 } // namespace ABI48_0_0React
115 } // namespace ABI48_0_0facebook
116