]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/Stopwatch.h
879a0b661b0e713c41fa1aebbb1166ee880be46c
[thirdparty/squid.git] / src / base / Stopwatch.h
1 /*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID_SRC_BASE_STOPWATCH_H
10 #define SQUID_SRC_BASE_STOPWATCH_H
11
12 #include <chrono>
13 #include <cstdint>
14
15 /// Quickly accumulates related real-time (a.k.a. "physical time" or "wall
16 /// clock") periods. Continues to run if the caller is blocked on a system call.
17 /// Usually suitable for measuring CPU overheads of non-sleeping code sequences.
18 class Stopwatch
19 {
20 public:
21 // std::clock() is not precise enough and raises (minor) overflow concerns;
22 // clock_gettime(CLOCK_PROCESS_CPUTIME_ID) may not be portable, and both may
23 // include CPU ticks accumulated by [AUFS] threads. When the code does
24 // not sleep (i.e. always does something), wall clock time is better.
25
26 // Do not be tempted by std::high_resolution_clock spelling! That clock has
27 // unpredictable properties. It may not be steady (i.e. !is_steady). Its use
28 // is discouraged[1,3]. In most implementations, the steady_clock resolution
29 // is just as high[1,2,3].
30 // [1]: https://en.cppreference.com/w/cpp/chrono/high_resolution_clock
31 // [2]: https://howardhinnant.github.io/clock_survey.html
32 // [3]: https://stackoverflow.com/questions/38252022/does-standard-c11-guarantee-that-high-resolution-clock-measure-real-time-non
33
34 /// the underlying time measuring mechanism
35 using Clock = std::chrono::steady_clock;
36
37 Stopwatch();
38
39 /// whether we are currently measuring time (i.e. between resume() and pause())
40 bool running() const { return resumes_ > pauses_; }
41
42 /// whether we ever measured time (i.e. resume() has been called)
43 bool ran() const { return resumes_ > 0; }
44
45 /// the sum of all measurement period durations (or zero)
46 /// includes the current measurement period, if any
47 Clock::duration total() const;
48
49 /// (re)starts or continues the current measurement period; each resume()
50 /// call must be paired with a dedicated future pause() call
51 void resume();
52
53 /// ends the current measurement period if needed; each pause() call
54 /// requires a prior dedicated resume() call
55 void pause();
56
57 private:
58 Clock::time_point runStart_; ///< when the current period was initiated
59
60 Clock::duration subtotal_; ///< the sum of all _finished_ periods
61
62 uint64_t resumes_ = 0; ///< the total number of resume() calls
63 uint64_t pauses_ = 0; ///< the total number of pause() calls
64 };
65
66 #endif /* SQUID_SRC_BASE_STOPWATCH_H */
67