1 #ifndef BENCHMARK_THREAD_TIMER_H
2 #define BENCHMARK_THREAD_TIMER_H
3 
4 #include "check.h"
5 #include "timers.h"
6 
7 namespace benchmark {
8 namespace internal {
9 
10 class ThreadTimer {
11  public:
12   ThreadTimer() = default;
13 
14   // Called by each thread
StartTimer()15   void StartTimer() {
16     running_ = true;
17     start_real_time_ = ChronoClockNow();
18     start_cpu_time_ = ThreadCPUUsage();
19   }
20 
21   // Called by each thread
StopTimer()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
SetIterationTime(double seconds)32   void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
33 
running()34   bool running() const { return running_; }
35 
36   // REQUIRES: timer is not running
real_time_used()37   double real_time_used() {
38     CHECK(!running_);
39     return real_time_used_;
40   }
41 
42   // REQUIRES: timer is not running
cpu_time_used()43   double cpu_time_used() {
44     CHECK(!running_);
45     return cpu_time_used_;
46   }
47 
48   // REQUIRES: timer is not running
manual_time_used()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