YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/monotime.cc
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
33
#include "yb/util/monotime.h"
34
35
#include <glog/logging.h>
36
37
#include "yb/gutil/casts.h"
38
#include "yb/gutil/stringprintf.h"
39
#include "yb/gutil/sysinfo.h"
40
41
#include "yb/util/result.h"
42
#include "yb/util/thread_restrictions.h"
43
44
#if defined(__APPLE__)
45
#include "yb/gutil/walltime.h"
46
#endif
47
48
using namespace std::literals;
49
50
namespace yb {
51
52
#define MAX_MONOTONIC_SECONDS \
53
  (((1ULL<<63) - 1ULL) /(int64_t)MonoTime::kNanosecondsPerSecond)
54
55
namespace {
56
57
2.07M
bool SafeToAdd64(int64_t a, int64_t b) {
58
2.07M
  bool negativeA = a < 0;
59
2.07M
  bool negativeB = b < 0;
60
2.07M
  if (negativeA != negativeB) {
61
140
    return true;
62
140
  }
63
2.07M
  bool negativeSum = (a + b) < 0;
64
2.07M
  return negativeSum == negativeA;
65
2.07M
}
66
67
} // namespace
68
69
///
70
/// MonoDelta
71
///
72
73
const MonoDelta::NanoDeltaType MonoDelta::kUninitialized =
74
    std::numeric_limits<NanoDeltaType>::min();
75
const MonoDelta MonoDelta::kMin = MonoDelta(std::numeric_limits<NanoDeltaType>::min() + 1);
76
const MonoDelta MonoDelta::kMax = MonoDelta(std::numeric_limits<NanoDeltaType>::max());
77
const MonoDelta MonoDelta::kZero = MonoDelta(0);
78
79
template <class V>
80
89.2M
MonoDelta MonoDeltaByMultiplication(V value, int64_t mul) {
81
89.2M
  CHECK_LE(value, std::numeric_limits<int64_t>::max() / mul);
82
89.2M
  int64_t delta = value * mul;
83
89.2M
  return MonoDelta::FromNanoseconds(delta);
84
89.2M
}
_ZN2yb25MonoDeltaByMultiplicationIdEENS_9MonoDeltaET_x
Line
Count
Source
80
354k
MonoDelta MonoDeltaByMultiplication(V value, int64_t mul) {
81
354k
  CHECK_LE(value, std::numeric_limits<int64_t>::max() / mul);
82
354k
  int64_t delta = value * mul;
83
354k
  return MonoDelta::FromNanoseconds(delta);
84
354k
}
_ZN2yb25MonoDeltaByMultiplicationIxEENS_9MonoDeltaET_x
Line
Count
Source
80
88.8M
MonoDelta MonoDeltaByMultiplication(V value, int64_t mul) {
81
88.8M
  CHECK_LE(value, std::numeric_limits<int64_t>::max() / mul);
82
88.8M
  int64_t delta = value * mul;
83
88.8M
  return MonoDelta::FromNanoseconds(delta);
84
88.8M
}
85
86
0
MonoDelta MonoDelta::FromMinutes(double minutes) {
87
0
  return MonoDeltaByMultiplication(minutes, MonoTime::kNanosecondsPerMinute);
88
0
}
89
90
354k
MonoDelta MonoDelta::FromSeconds(double seconds) {
91
354k
  return MonoDeltaByMultiplication(seconds, MonoTime::kNanosecondsPerSecond);
92
354k
}
93
94
71.8M
MonoDelta MonoDelta::FromMilliseconds(int64_t ms) {
95
71.8M
  return MonoDeltaByMultiplication(ms, MonoTime::kNanosecondsPerMillisecond);
96
71.8M
}
97
98
17.0M
MonoDelta MonoDelta::FromMicroseconds(int64_t us) {
99
17.0M
  return MonoDeltaByMultiplication(us, MonoTime::kNanosecondsPerMicrosecond);
100
17.0M
}
101
102
89.4M
MonoDelta MonoDelta::FromNanoseconds(int64_t ns) {
103
89.4M
  return MonoDelta(ns);
104
89.4M
}
105
106
166M
MonoDelta::MonoDelta() noexcept : nano_delta_(kUninitialized) {
107
166M
}
108
109
1.89G
bool MonoDelta::Initialized() const {
110
1.89G
  return nano_delta_ != kUninitialized;
111
1.89G
}
112
113
79.2M
bool MonoDelta::LessThan(const MonoDelta &rhs) const {
114
79.2M
  DCHECK(Initialized());
115
79.2M
  DCHECK(rhs.Initialized());
116
79.2M
  return nano_delta_ < rhs.nano_delta_;
117
79.2M
}
118
119
1.18k
bool MonoDelta::MoreThan(const MonoDelta &rhs) const {
120
1.18k
  DCHECK(Initialized());
121
1.18k
  DCHECK(rhs.Initialized());
122
1.18k
  return nano_delta_ > rhs.nano_delta_;
123
1.18k
}
124
125
229M
bool MonoDelta::Equals(const MonoDelta &rhs) const {
126
229M
  DCHECK(Initialized());
127
229M
  DCHECK(rhs.Initialized());
128
229M
  return nano_delta_ == rhs.nano_delta_;
129
229M
}
130
131
28.1M
bool MonoDelta::IsNegative() const {
132
28.1M
  DCHECK(Initialized());
133
28.1M
  return nano_delta_ < 0;
134
28.1M
}
135
136
512k
std::string MonoDelta::ToString() const {
137
418k
  return Initialized() ? StringPrintf("%.3fs", ToSeconds()) : "<uninitialized>";
138
512k
}
139
140
MonoDelta::MonoDelta(int64_t delta)
141
90.5M
  : nano_delta_(delta) {
142
90.5M
}
143
144
128M
double MonoDelta::ToSeconds() const {
145
128M
  DCHECK(Initialized());
146
128M
  double d(nano_delta_);
147
128M
  d /= MonoTime::kNanosecondsPerSecond;
148
128M
  return d;
149
128M
}
150
151
0
double MonoDelta::ToMinutes() const {
152
0
  auto seconds = ToSeconds();
153
0
  return seconds / MonoTime::kSecondsPerMinute;
154
0
}
155
156
306M
int64_t MonoDelta::ToNanoseconds() const {
157
306M
  DCHECK(Initialized());
158
306M
  return nano_delta_;
159
306M
}
160
161
242M
std::chrono::steady_clock::duration MonoDelta::ToSteadyDuration() const {
162
242M
  return std::chrono::nanoseconds(ToNanoseconds());
163
242M
}
164
165
264M
int64_t MonoDelta::ToMicroseconds() const {
166
264M
  DCHECK(Initialized());
167
264M
  return nano_delta_ / MonoTime::kNanosecondsPerMicrosecond;
168
264M
}
169
170
105M
int64_t MonoDelta::ToMilliseconds() const {
171
105M
  DCHECK(Initialized());
172
105M
  return nano_delta_ / MonoTime::kNanosecondsPerMillisecond;
173
105M
}
174
175
2.01M
MonoDelta& MonoDelta::operator+=(const MonoDelta& rhs) {
176
2.01M
  DCHECK(Initialized());
177
2.01M
  DCHECK(rhs.Initialized());
178
2.01M
  DCHECK(SafeToAdd64(nano_delta_, rhs.nano_delta_));
179
2.01M
  DCHECK(nano_delta_ + rhs.nano_delta_ != kUninitialized);
180
2.01M
  nano_delta_ += rhs.nano_delta_;
181
2.01M
  return *this;
182
2.01M
}
183
184
53.5k
MonoDelta& MonoDelta::operator-=(const MonoDelta& rhs) {
185
53.5k
  DCHECK(Initialized());
186
53.5k
  DCHECK(rhs.Initialized());
187
53.5k
  DCHECK(SafeToAdd64(nano_delta_, -rhs.nano_delta_));
188
53.5k
  DCHECK(nano_delta_ - rhs.nano_delta_ != kUninitialized);
189
53.5k
  nano_delta_ -= rhs.nano_delta_;
190
53.5k
  return *this;
191
53.5k
}
192
193
119M
MonoDelta& MonoDelta::operator*=(int64_t mul) {
194
119M
  DCHECK(Initialized());
195
  DCHECK(mul == 0 || (nano_delta_ * mul / mul == nano_delta_)) // Check for overflow
196
50.6k
      << "Mul: " << mul << ", nano_delta_: " << nano_delta_;
197
119M
  DCHECK(nano_delta_ * mul != kUninitialized);
198
119M
  nano_delta_ *= mul;
199
119M
  return *this;
200
119M
}
201
202
21
MonoDelta& MonoDelta::operator/=(int64_t divisor) {
203
21
  DCHECK(Initialized());
204
21
  DCHECK_NE(divisor, 0);
205
21
  nano_delta_ /= divisor;
206
21
  return *this;
207
21
}
208
209
1.88M
void MonoDelta::ToTimeVal(struct timeval *tv) const {
210
1.88M
  DCHECK(Initialized());
211
1.88M
  tv->tv_sec = nano_delta_ / MonoTime::kNanosecondsPerSecond;
212
1.88M
  tv->tv_usec = narrow_cast<int32_t>(
213
1.88M
      (nano_delta_ - tv->tv_sec * MonoTime::kNanosecondsPerSecond)
214
1.88M
      / MonoTime::kNanosecondsPerMicrosecond);
215
216
  // tv_usec must be between 0 and 999999.
217
  // There is little use for negative timevals so wrap it in PREDICT_FALSE.
218
1.88M
  if (PREDICT_FALSE(tv->tv_usec < 0)) {
219
1
    --(tv->tv_sec);
220
1
    tv->tv_usec += MonoTime::kMicrosecondsPerSecond;
221
1
  }
222
223
  // Catch positive corner case where we "round down" and could potentially set a timeout of 0.
224
  // Make it 1 usec.
225
1.88M
  if (PREDICT_FALSE(tv->tv_usec == 0 && tv->tv_sec == 0 && nano_delta_ > 0)) {
226
1
    tv->tv_usec = 1;
227
1
  }
228
229
  // Catch negative corner case where we "round down" and could potentially set a timeout of 0.
230
  // Make it -1 usec (but normalized, so tv_usec is not negative).
231
1.88M
  if (PREDICT_FALSE(tv->tv_usec == 0 && tv->tv_sec == 0 && nano_delta_ < 0)) {
232
1
    tv->tv_sec = -1;
233
1
    tv->tv_usec = 999999;
234
1
  }
235
1.88M
}
236
237
238
45.7M
void MonoDelta::NanosToTimeSpec(int64_t nanos, struct timespec* ts) {
239
45.7M
  ts->tv_sec = nanos / MonoTime::kNanosecondsPerSecond;
240
45.7M
  ts->tv_nsec = nanos - (ts->tv_sec * MonoTime::kNanosecondsPerSecond);
241
242
  // tv_nsec must be between 0 and 999999999.
243
  // There is little use for negative timespecs so wrap it in PREDICT_FALSE.
244
45.7M
  if (PREDICT_FALSE(ts->tv_nsec < 0)) {
245
1
    --(ts->tv_sec);
246
1
    ts->tv_nsec += MonoTime::kNanosecondsPerSecond;
247
1
  }
248
45.7M
}
249
250
45.7M
void MonoDelta::ToTimeSpec(struct timespec *ts) const {
251
45.7M
  DCHECK(Initialized());
252
45.7M
  NanosToTimeSpec(nano_delta_, ts);
253
45.7M
}
254
255
///
256
/// MonoTime
257
///
258
259
const MonoTime MonoTime::kMin = MonoTime::Min();
260
const MonoTime MonoTime::kMax = MonoTime::Max();
261
const MonoTime MonoTime::kUninitialized = MonoTime();
262
263
564M
MonoTime MonoTime::Now() {
264
564M
  return MonoTime(std::chrono::steady_clock::now());
265
564M
}
266
267
178k
MonoTime MonoTime::Max() {
268
178k
  return MonoTime(std::chrono::steady_clock::time_point::max());
269
178k
}
270
271
1.04M
MonoTime MonoTime::Min() {
272
1.04M
  return MonoTime(std::chrono::steady_clock::time_point(std::chrono::steady_clock::duration(1)));
273
1.04M
}
274
275
2.90k
bool MonoTime::IsMax() const {
276
2.90k
  return Equals(kMax);
277
2.90k
}
278
279
2.89k
bool MonoTime::IsMin() const {
280
2.89k
  return Equals(kMin);
281
2.89k
}
282
283
271k
const MonoTime& MonoTime::Earliest(const MonoTime& a, const MonoTime& b) {
284
271k
  return std::min(a, b);
285
271k
}
286
287
298M
MonoDelta MonoTime::GetDeltaSince(const MonoTime &rhs) const {
288
298M
  DCHECK(Initialized());
289
298M
  DCHECK(rhs.Initialized());
290
298M
  return MonoDelta(value_ - rhs.value_);
291
298M
}
292
293
82.9M
void MonoTime::AddDelta(const MonoDelta &delta) {
294
82.9M
  DCHECK(Initialized());
295
82.9M
  DCHECK(delta.Initialized());
296
82.9M
  if (delta == MonoDelta::kMax) {
297
0
    value_ = kMax.value_;
298
82.9M
  } else {
299
82.9M
    value_ += delta.ToSteadyDuration();
300
82.9M
  }
301
82.9M
}
302
303
1
void MonoTime::SubtractDelta(const MonoDelta &delta) {
304
1
  DCHECK(Initialized());
305
1
  DCHECK(delta.Initialized());
306
1
  if (delta == MonoDelta::kMin) {
307
0
    value_ = kMin.value_;
308
1
  } else {
309
1
    value_ -= delta.ToSteadyDuration();
310
1
  }
311
1
}
312
313
27.7M
bool MonoTime::ComesBefore(const MonoTime &rhs) const {
314
27.7M
  DCHECK(Initialized());
315
27.7M
  DCHECK(rhs.Initialized());
316
27.7M
  return value_ < rhs.value_;
317
27.7M
}
318
319
2.90k
std::string MonoTime::ToString() const {
320
2.90k
  if (!Initialized())
321
0
    return "MonoTime::kUninitialized";
322
2.90k
  if (IsMax())
323
0
    return "MonoTime::kMax";
324
2.90k
  if (IsMin())
325
0
    return "MonoTime::kMin";
326
2.90k
  return StringPrintf("%.3fs", ToSeconds());
327
2.90k
}
328
329
14.4k
bool MonoTime::Equals(const MonoTime& other) const {
330
14.4k
  return value_ == other.value_;
331
14.4k
}
332
333
2.89k
double MonoTime::ToSeconds() const {
334
2.89k
  return yb::ToSeconds(value_.time_since_epoch());
335
2.89k
}
336
337
0
void MonoTime::MakeAtLeast(MonoTime rhs) {
338
0
  if (rhs.Initialized() && (!Initialized() || value_ < rhs.value_)) {
339
0
    value_ = rhs.value_;
340
0
  }
341
0
}
342
343
// ------------------------------------------------------------------------------------------------
344
345
0
std::string FormatForComparisonFailureMessage(const MonoDelta& op, const MonoDelta& other) {
346
0
  return op.ToString();
347
0
}
348
349
2.05M
void SleepFor(const MonoDelta& delta) {
350
2.05M
  ThreadRestrictions::AssertWaitAllowed();
351
2.05M
  base::SleepForNanoseconds(delta.ToNanoseconds());
352
2.05M
}
353
354
992M
CoarseMonoClock::time_point CoarseMonoClock::now() {
355
992M
#if defined(__APPLE__)
356
992M
  int64_t nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(
357
992M
      std::chrono::steady_clock::now().time_since_epoch()).count();
358
# else
359
  struct timespec ts;
360
  PCHECK(clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0);
361
  CHECK_LT(ts.tv_sec, MAX_MONOTONIC_SECONDS);
362
  int64_t nanos = static_cast<int64_t>(ts.tv_sec) * MonoTime::kNanosecondsPerSecond + ts.tv_nsec;
363
#endif // defined(__APPLE__)
364
992M
  return time_point(duration(nanos));
365
992M
}
366
367
template <>
368
39.9k
CoarseMonoClock::Duration ClockResolution<CoarseMonoClock>() {
369
39.9k
#if defined(__APPLE__)
370
39.9k
  return std::chrono::duration_cast<CoarseMonoClock::Duration>(
371
39.9k
      std::chrono::steady_clock::duration(1));
372
#else
373
  struct timespec res;
374
  if (clock_getres(CLOCK_MONOTONIC_COARSE, &res) == 0) {
375
    auto resolution = std::chrono::seconds(res.tv_sec) + std::chrono::nanoseconds(res.tv_nsec);
376
    return std::chrono::duration_cast<CoarseMonoClock::Duration>(resolution);
377
  }
378
  return CoarseMonoClock::Duration(1);
379
#endif // defined(__APPLE__)
380
39.9k
}
381
382
82.6k
std::string ToString(CoarseMonoClock::TimePoint time_point) {
383
82.6k
  return MonoDelta(time_point.time_since_epoch()).ToString();
384
82.6k
}
385
386
53.7M
CoarseTimePoint ToCoarse(MonoTime monotime) {
387
53.7M
  return CoarseTimePoint(monotime.ToSteadyTimePoint().time_since_epoch());
388
53.7M
}
389
390
430k
std::chrono::steady_clock::time_point ToSteady(CoarseTimePoint time_point) {
391
430k
  return std::chrono::steady_clock::time_point(time_point.time_since_epoch());
392
430k
}
393
394
} // namespace yb