1#ifndef BENCHMARK_THREAD_TIMER_H
2#define BENCHMARK_THREAD_TIMER_H
3
4#include "check.h"
5#include "timers.h"
6
7namespace benchmark {
8namespace internal {
9
10class ThreadTimer {
11 public:
12  ThreadTimer() = default;
13
14  // Called by each thread
15  void StartTimer() {
16    running_ = true;
17    start_real_time_ = ChronoClockNow();
18    start_cpu_time_ = ThreadCPUUsage();
19  }
20
21  // Called by each thread
22  void StopTimer() {
23    CHECK(running_);
24    running_ = false;
25    real_time_used_ += ChronoClockNow() - start_real_time_;
26    // Floating point error can result in the subtraction producing a negative
27    // time. Guard against that.
28    cpu_time_used_ += std::max<double>(ThreadCPUUsage() - start_cpu_time_, 0);
29  }
30
31  // Called by each thread
32  void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
33
34  bool running() const { return running_; }
35
36  // REQUIRES: timer is not running
37  double real_time_used() {
38    CHECK(!running_);
39    return real_time_used_;
40  }
41
42  // REQUIRES: timer is not running
43  double cpu_time_used() {
44    CHECK(!running_);
45    return cpu_time_used_;
46  }
47
48  // REQUIRES: timer is not running
49  double manual_time_used() {
50    CHECK(!running_);
51    return manual_time_used_;
52  }
53
54 private:
55  bool running_ = false;        // Is the timer running
56  double start_real_time_ = 0;  // If running_
57  double start_cpu_time_ = 0;   // If running_
58
59  // Accumulated time so far (does not contain current slice if running_)
60  double real_time_used_ = 0;
61  double cpu_time_used_ = 0;
62  // Manually set iteration time. User sets this with SetIterationTime(seconds).
63  double manual_time_used_ = 0;
64};
65
66}  // namespace internal
67}  // namespace benchmark
68
69#endif  // BENCHMARK_THREAD_TIMER_H
70