YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/util/monotime.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
#ifndef YB_UTIL_MONOTIME_H
33
#define YB_UTIL_MONOTIME_H
34
35
#include <chrono>
36
#include <cstdint>
37
#include <string>
38
39
#include <gtest/gtest_prod.h>
40
41
struct timeval;
42
struct timespec;
43
44
namespace yb {
45
class MonoTime;
46
47
// Represent an elapsed duration of time -- i.e the delta between
48
// two MonoTime instances.
49
//
50
// A MonoDelta built with the default constructor is "uninitialized" and
51
// may not be used for any operation.
52
class MonoDelta {
53
 public:
54
  static MonoDelta FromMinutes(double minutes);
55
  static MonoDelta FromSeconds(double seconds);
56
  static MonoDelta FromMilliseconds(int64_t ms);
57
  static MonoDelta FromMicroseconds(int64_t us);
58
  static MonoDelta FromNanoseconds(int64_t ns);
59
60
  static const MonoDelta kMin;
61
  static const MonoDelta kMax;
62
  static const MonoDelta kZero;
63
64
  MonoDelta() noexcept;
65
66
  template<class Rep, class Period>
67
  MonoDelta(const std::chrono::duration<Rep, Period>& duration) // NOLINT
68
2.88G
      : nano_delta_(std::chrono::nanoseconds(duration).count()) {}
yb::MonoDelta::MonoDelta<long long, std::__1::ratio<1l, 1l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l> > const&)
Line
Count
Source
68
493M
      : nano_delta_(std::chrono::nanoseconds(duration).count()) {}
yb::MonoDelta::MonoDelta<long long, std::__1::ratio<1l, 1000l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> > const&)
Line
Count
Source
68
64.9M
      : nano_delta_(std::chrono::nanoseconds(duration).count()) {}
yb::MonoDelta::MonoDelta<long long, std::__1::ratio<1l, 1000000000l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > const&)
Line
Count
Source
68
2.31G
      : nano_delta_(std::chrono::nanoseconds(duration).count()) {}
yb::MonoDelta::MonoDelta<long long, std::__1::ratio<1l, 1000000l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000l> > const&)
Line
Count
Source
68
695k
      : nano_delta_(std::chrono::nanoseconds(duration).count()) {}
yb::MonoDelta::MonoDelta<unsigned long long, std::__1::ratio<1l, 1000l> >(std::__1::chrono::duration<unsigned long long, std::__1::ratio<1l, 1000l> > const&)
Line
Count
Source
68
7.59M
      : nano_delta_(std::chrono::nanoseconds(duration).count()) {}
69
70
  bool Initialized() const;
71
  bool LessThan(const MonoDelta &rhs) const;
72
  bool MoreThan(const MonoDelta &rhs) const;
73
  bool Equals(const MonoDelta &rhs) const;
74
  bool IsNegative() const;
75
  std::string ToString() const;
76
  double ToSeconds() const;
77
  double ToMinutes() const;
78
  int64_t ToMilliseconds() const;
79
  int64_t ToMicroseconds() const;
80
  int64_t ToNanoseconds() const;
81
  std::chrono::steady_clock::duration ToSteadyDuration() const;
82
83
0
  std::chrono::microseconds ToChronoMicroseconds() const {
84
0
    return std::chrono::microseconds(ToMicroseconds());
85
0
  }
86
87
0
  std::chrono::milliseconds ToChronoMilliseconds() const {
88
0
    return std::chrono::milliseconds(ToMilliseconds());
89
0
  }
90
91
  MonoDelta& operator+=(const MonoDelta& rhs);
92
  MonoDelta& operator-=(const MonoDelta& rhs);
93
  MonoDelta& operator*=(int64_t mul);
94
  MonoDelta& operator/=(int64_t mul);
95
96
  // Update struct timeval to current value of delta, with microsecond accuracy.
97
  // Note that if MonoDelta::IsPositive() returns true, the struct timeval
98
  // is guaranteed to hold a positive number as well (at least 1 microsecond).
99
  void ToTimeVal(struct timeval *tv) const;
100
101
  // Update struct timespec to current value of delta, with nanosecond accuracy.
102
  void ToTimeSpec(struct timespec *ts) const;
103
104
  // Convert a nanosecond value to a timespec.
105
  static void NanosToTimeSpec(int64_t nanos, struct timespec* ts);
106
107
114M
  explicit operator bool() const { return Initialized(); }
108
53.7M
  bool operator !() const { return !Initialized(); }
109
110
4.00M
  MonoDelta operator-() const { return MonoDelta(-nano_delta_); }
111
112
 private:
113
  typedef int64_t NanoDeltaType;
114
  static const NanoDeltaType kUninitialized;
115
116
  FRIEND_TEST(TestMonoTime, TestDeltaConversions);
117
  explicit MonoDelta(NanoDeltaType delta);
118
  NanoDeltaType nano_delta_;
119
};
120
121
120M
inline bool operator<(MonoDelta lhs, MonoDelta rhs) { return lhs.LessThan(rhs); }
122
113M
inline bool operator>(MonoDelta lhs, MonoDelta rhs) { return rhs < lhs; }
123
77.7k
inline bool operator>=(MonoDelta lhs, MonoDelta rhs) { return !(lhs < rhs); }
124
8.09k
inline bool operator<=(MonoDelta lhs, MonoDelta rhs) { return !(rhs < lhs); }
125
126
386M
inline bool operator==(MonoDelta lhs, MonoDelta rhs) { return lhs.Equals(rhs); }
127
99.8M
inline bool operator!=(MonoDelta lhs, MonoDelta rhs) { return !(rhs == lhs); }
128
129
std::string FormatForComparisonFailureMessage(const MonoDelta& op, const MonoDelta& other);
130
131
75.0k
inline MonoDelta operator-(MonoDelta lhs, MonoDelta rhs) { return lhs -= rhs; }
132
10.2M
inline MonoDelta operator+(MonoDelta lhs, MonoDelta rhs) { return lhs += rhs; }
133
371M
inline MonoDelta operator*(MonoDelta lhs, int64_t rhs) { return lhs *= rhs; }
134
24
inline MonoDelta operator/(MonoDelta lhs, int64_t rhs) { return lhs /= rhs; }
135
136
349k
inline std::ostream& operator<<(std::ostream& out, MonoDelta delta) {
137
349k
  return out << delta.ToString();
138
349k
}
139
140
// Represent a particular point in time, relative to some fixed but unspecified
141
// reference point.
142
//
143
// This time is monotonic, meaning that if the user changes his or her system
144
// clock, the monotime does not change.
145
class MonoTime {
146
 public:
147
  static constexpr int64_t kNanosecondsPerMicrosecond = 1000L;
148
  static constexpr int64_t kMicrosecondsPerMillisecond = 1000L;
149
  static constexpr int64_t kMillisecondsPerSecond = 1000L;
150
  static constexpr int64_t kSecondsPerMinute = 60L;
151
152
  static constexpr int64_t kNanosecondsPerMillisecond =
153
      kNanosecondsPerMicrosecond * kMicrosecondsPerMillisecond;
154
155
  static constexpr int64_t kMicrosecondsPerSecond =
156
      kMillisecondsPerSecond * kMicrosecondsPerMillisecond;
157
158
  static constexpr int64_t kNanosecondsPerSecond =
159
      kNanosecondsPerMillisecond * kMillisecondsPerSecond;
160
161
  static constexpr int64_t kNanosecondsPerMinute =
162
      kNanosecondsPerSecond * kSecondsPerMinute;
163
164
  static const MonoTime kMin;
165
  static const MonoTime kMax;
166
  static const MonoTime kUninitialized;
167
168
  // The coarse monotonic time is faster to retrieve, but "only" accurate to within a millisecond or
169
  // two.  The speed difference will depend on your timer hardware.
170
  static MonoTime Now();
171
172
  // Return MonoTime equal to farthest possible time into the future.
173
  static MonoTime Max();
174
175
  // Return MonoTime equal to farthest possible time into the past.
176
  static MonoTime Min();
177
178
  // Return the earliest (minimum) of the two monotimes.
179
  static const MonoTime& Earliest(const MonoTime& a, const MonoTime& b);
180
181
714M
  MonoTime() noexcept {}
182
1.47G
  MonoTime(std::chrono::steady_clock::time_point value) : value_(value) {} // NOLINT
183
184
2.23G
  bool Initialized() const { return value_ != std::chrono::steady_clock::time_point(); }
185
186
  MonoDelta GetDeltaSince(const MonoTime &rhs) const;
187
0
  MonoDelta GetDeltaSinceMin() const { return GetDeltaSince(Min()); }
188
  void AddDelta(const MonoDelta &delta);
189
  void SubtractDelta(const MonoDelta &delta);
190
  bool ComesBefore(const MonoTime &rhs) const;
191
  std::string ToString() const;
192
  bool Equals(const MonoTime& other) const;
193
  bool IsMax() const;
194
  bool IsMin() const;
195
196
49.9k
  uint64_t ToUint64() const { return value_.time_since_epoch().count(); }
197
50.6k
  static MonoTime FromUint64(uint64_t value) {
198
50.6k
    return MonoTime(std::chrono::steady_clock::time_point(std::chrono::steady_clock::duration(
199
50.6k
        value)));
200
50.6k
  }
201
202
1.08k
  explicit operator bool() const { return Initialized(); }
203
0
  bool operator !() const { return !Initialized(); }
204
205
  // Set this time to the given value if it is lower than that or uninitialized.
206
  void MakeAtLeast(MonoTime rhs);
207
208
184M
  std::chrono::steady_clock::time_point ToSteadyTimePoint() const {
209
184M
    return value_;
210
184M
  }
211
212
 private:
213
  double ToSeconds() const;
214
215
  std::chrono::steady_clock::time_point value_;
216
};
217
218
131M
inline MonoTime& operator+=(MonoTime& lhs, const MonoDelta& rhs) { // NOLINT
219
131M
  lhs.AddDelta(rhs);
220
131M
  return lhs;
221
131M
}
222
223
131M
inline MonoTime operator+(MonoTime lhs, const MonoDelta& rhs) {
224
131M
  lhs += rhs;
225
131M
  return lhs;
226
131M
}
227
228
template <class Clock>
229
399M
inline auto operator+(const std::chrono::time_point<Clock>& lhs, const MonoDelta& rhs) {
230
399M
  return lhs + rhs.ToSteadyDuration();
231
399M
}
232
233
315M
inline MonoDelta operator-(const MonoTime& lhs, const MonoTime& rhs) {
234
315M
  return lhs.GetDeltaSince(rhs);
235
315M
}
236
237
0
inline MonoTime& operator-=(MonoTime& lhs, const MonoDelta& rhs) { // NOLINT
238
0
  lhs.SubtractDelta(rhs);
239
0
  return lhs;
240
0
}
241
242
4.00M
inline MonoTime operator-(const MonoTime& lhs, const MonoDelta& rhs) {
243
4.00M
  MonoTime result = lhs;
244
4.00M
  result.AddDelta(-rhs);
245
4.00M
  return MonoTime(result);
246
4.00M
}
247
248
56.4M
inline bool operator<(const MonoTime& lhs, const MonoTime& rhs) {
249
56.4M
  return lhs.ComesBefore(rhs);
250
56.4M
}
251
252
25.0M
inline bool operator>(const MonoTime& lhs, const MonoTime& rhs) { return rhs < lhs; }
253
0
inline bool operator<=(const MonoTime& lhs, const MonoTime& rhs) { return !(rhs < lhs); }
254
14.4k
inline bool operator>=(const MonoTime& lhs, const MonoTime& rhs) { return !(lhs < rhs); }
255
256
619k
inline bool operator==(const MonoTime& lhs, const MonoTime& rhs) { return lhs.Equals(rhs); }
257
1.22k
inline bool operator!=(const MonoTime& lhs, const MonoTime& rhs) { return !(lhs == rhs); }
258
259
// Sleep for a MonoDelta duration.
260
//
261
// This is preferred over sleep(3), usleep(3), and nanosleep(3). It's less prone to mixups with
262
// units since it uses a MonoDelta. It also ignores EINTR, so will reliably sleep at least the
263
// MonoDelta duration.
264
void SleepFor(const MonoDelta& delta);
265
266
class CoarseMonoClock {
267
 public:
268
  typedef std::chrono::nanoseconds duration;
269
  typedef duration Duration;
270
  typedef std::chrono::time_point<CoarseMonoClock> time_point;
271
  typedef time_point TimePoint;
272
273
  static constexpr bool is_steady = true;
274
275
  static time_point now();
276
3.05G
  static TimePoint Now() { return now(); }
277
};
278
279
template <class Clock>
280
20.7k
typename Clock::duration ClockResolution() {
281
20.7k
  return typename Clock::duration(1);
282
20.7k
}
283
284
template <>
285
CoarseMonoClock::Duration ClockResolution<CoarseMonoClock>();
286
287
typedef CoarseMonoClock::TimePoint CoarseTimePoint;
288
typedef CoarseMonoClock::Duration CoarseDuration;
289
290
template <class Rep, class Period>
291
41.3k
int64_t ToMilliseconds(const std::chrono::duration<Rep, Period>& duration) {
292
41.3k
  return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
293
41.3k
}
294
295
template <class Rep, class Period>
296
23.8M
int64_t ToMicroseconds(const std::chrono::duration<Rep, Period>& duration) {
297
23.8M
  return std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
298
23.8M
}
long long yb::ToMicroseconds<long long, std::__1::ratio<1l, 1000000000l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > const&)
Line
Count
Source
296
23.8M
int64_t ToMicroseconds(const std::chrono::duration<Rep, Period>& duration) {
297
23.8M
  return std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
298
23.8M
}
long long yb::ToMicroseconds<long long, std::__1::ratio<1l, 1l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l> > const&)
Line
Count
Source
296
251
int64_t ToMicroseconds(const std::chrono::duration<Rep, Period>& duration) {
297
251
  return std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
298
251
}
299
300
template <class Rep, class Period>
301
int64_t ToNanoseconds(const std::chrono::duration<Rep, Period>& duration) {
302
  return std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
303
}
304
305
template <class Rep, class Period>
306
884k
double ToSeconds(const std::chrono::duration<Rep, Period>& duration) {
307
884k
  return duration.count() /
308
884k
      static_cast<double>(std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(
309
884k
          std::chrono::seconds(1)).count());
310
884k
}
311
312
inline double ToSeconds(MonoDelta delta) {
313
  return delta.ToSeconds();
314
}
315
316
std::string ToString(CoarseMonoClock::TimePoint value);
317
318
CoarseTimePoint ToCoarse(MonoTime monotime);
319
std::chrono::steady_clock::time_point ToSteady(CoarseTimePoint time_point);
320
321
} // namespace yb
322
323
#endif // YB_UTIL_MONOTIME_H