Coverage Report

Created: 2024-07-27 06:53

/src/rocksdb/util/stop_watch.h
Line
Count
Source (jump to first uncovered line)
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under both the GPLv2 (found in the
3
//  COPYING file in the root directory) and Apache 2.0 License
4
//  (found in the LICENSE.Apache file in the root directory).
5
//
6
#pragma once
7
#include "monitoring/statistics_impl.h"
8
#include "rocksdb/system_clock.h"
9
10
namespace ROCKSDB_NAMESPACE {
11
// Auto-scoped.
12
// When statistics is not nullptr, records the measured time into any enabled
13
// histograms supplied to the constructor. A histogram argument may be omitted
14
// by setting it to Histograms::HISTOGRAM_ENUM_MAX. It is also saved into
15
// *elapsed if the pointer is not nullptr and overwrite is true, it will be
16
// added to *elapsed if overwrite is false.
17
class StopWatch {
18
 public:
19
  StopWatch(SystemClock* clock, Statistics* statistics,
20
            const uint32_t hist_type_1,
21
            const uint32_t hist_type_2 = Histograms::HISTOGRAM_ENUM_MAX,
22
            uint64_t* elapsed = nullptr, bool overwrite = true,
23
            bool delay_enabled = false)
24
      : clock_(clock),
25
        statistics_(statistics),
26
        hist_type_1_(statistics && statistics->HistEnabledForType(hist_type_1)
27
                         ? hist_type_1
28
                         : Histograms::HISTOGRAM_ENUM_MAX),
29
        hist_type_2_(statistics && statistics->HistEnabledForType(hist_type_2)
30
                         ? hist_type_2
31
                         : Histograms::HISTOGRAM_ENUM_MAX),
32
        elapsed_(elapsed),
33
        overwrite_(overwrite),
34
        stats_enabled_(statistics &&
35
                       statistics->get_stats_level() >
36
                           StatsLevel::kExceptTimers &&
37
                       (hist_type_1_ != Histograms::HISTOGRAM_ENUM_MAX ||
38
                        hist_type_2_ != Histograms::HISTOGRAM_ENUM_MAX)),
39
        delay_enabled_(delay_enabled),
40
        total_delay_(0),
41
        delay_start_time_(0),
42
        start_time_((stats_enabled_ || elapsed != nullptr) ? clock->NowMicros()
43
5.53M
                                                           : 0) {}
44
45
5.53M
  ~StopWatch() {
46
5.53M
    if (elapsed_) {
47
0
      if (overwrite_) {
48
0
        *elapsed_ = clock_->NowMicros() - start_time_;
49
0
      } else {
50
0
        *elapsed_ += clock_->NowMicros() - start_time_;
51
0
      }
52
0
    }
53
5.53M
    if (elapsed_ && delay_enabled_) {
54
0
      *elapsed_ -= total_delay_;
55
0
    }
56
5.53M
    if (stats_enabled_) {
57
0
      const auto time = (elapsed_ != nullptr)
58
0
                            ? *elapsed_
59
0
                            : (clock_->NowMicros() - start_time_);
60
0
      if (hist_type_1_ != Histograms::HISTOGRAM_ENUM_MAX) {
61
0
        statistics_->reportTimeToHistogram(hist_type_1_, time);
62
0
      }
63
0
      if (hist_type_2_ != Histograms::HISTOGRAM_ENUM_MAX) {
64
0
        statistics_->reportTimeToHistogram(hist_type_2_, time);
65
0
      }
66
0
    }
67
5.53M
  }
68
69
0
  void DelayStart() {
70
    // if delay_start_time_ is not 0, it means we are already tracking delay,
71
    // so delay_start_time_ should not be overwritten
72
0
    if (elapsed_ && delay_enabled_ && delay_start_time_ == 0) {
73
0
      delay_start_time_ = clock_->NowMicros();
74
0
    }
75
0
  }
76
77
0
  void DelayStop() {
78
0
    if (elapsed_ && delay_enabled_ && delay_start_time_ != 0) {
79
0
      total_delay_ += clock_->NowMicros() - delay_start_time_;
80
0
    }
81
    // reset to 0 means currently no delay is being tracked, so two consecutive
82
    // calls to DelayStop will not increase total_delay_
83
0
    delay_start_time_ = 0;
84
0
  }
85
86
0
  uint64_t GetDelay() const { return delay_enabled_ ? total_delay_ : 0; }
87
88
0
  uint64_t start_time() const { return start_time_; }
89
90
 private:
91
  SystemClock* clock_;
92
  Statistics* statistics_;
93
  const uint32_t hist_type_1_;
94
  const uint32_t hist_type_2_;
95
  uint64_t* elapsed_;
96
  bool overwrite_;
97
  bool stats_enabled_;
98
  bool delay_enabled_;
99
  uint64_t total_delay_;
100
  uint64_t delay_start_time_;
101
  const uint64_t start_time_;
102
};
103
104
// a nano second precision stopwatch
105
class StopWatchNano {
106
 public:
107
  explicit StopWatchNano(SystemClock* clock, bool auto_start = false)
108
20.4k
      : clock_(clock), start_(0) {
109
20.4k
    if (auto_start) {
110
0
      Start();
111
0
    }
112
20.4k
  }
113
114
0
  void Start() { start_ = clock_->NowNanos(); }
115
116
0
  uint64_t ElapsedNanos(bool reset = false) {
117
0
    auto now = clock_->NowNanos();
118
0
    auto elapsed = now - start_;
119
0
    if (reset) {
120
0
      start_ = now;
121
0
    }
122
0
    return elapsed;
123
0
  }
124
125
0
  uint64_t ElapsedNanosSafe(bool reset = false) {
126
0
    return (clock_ != nullptr) ? ElapsedNanos(reset) : 0U;
127
0
  }
128
129
12.1k
  bool IsStarted() { return start_ != 0; }
130
131
 private:
132
  SystemClock* clock_;
133
  uint64_t start_;
134
};
135
136
}  // namespace ROCKSDB_NAMESPACE