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 explicit ThreadTimer(bool measure_process_cpu_time_)
12 : measure_process_cpu_time(measure_process_cpu_time_) {}
13
14 public:
15 static ThreadTimer Create() {
16 return ThreadTimer(/*measure_process_cpu_time_=*/false);
17 }
18 static ThreadTimer CreateProcessCpuTime() {
19 return ThreadTimer(/*measure_process_cpu_time_=*/true);
20 }
21
22 // Called by each thread
23 void StartTimer() {
24 running_ = true;
25 start_real_time_ = ChronoClockNow();
26 start_cpu_time_ = ReadCpuTimerOfChoice();
27 }
28
29 // Called by each thread
30 void StopTimer() {
31 BM_CHECK(running_);
32 running_ = false;
33 real_time_used_ += ChronoClockNow() - start_real_time_;
34 // Floating point error can result in the subtraction producing a negative
35 // time. Guard against that.
36 cpu_time_used_ +=
37 std::max<double>(ReadCpuTimerOfChoice() - start_cpu_time_, 0);
38 }
39
40 // Called by each thread
41 void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
42
43 bool running() const { return running_; }
44
45 // REQUIRES: timer is not running
46 double real_time_used() const {
47 BM_CHECK(!running_);
48 return real_time_used_;
49 }
50
51 // REQUIRES: timer is not running
52 double cpu_time_used() const {
53 BM_CHECK(!running_);
54 return cpu_time_used_;
55 }
56
57 // REQUIRES: timer is not running
58 double manual_time_used() const {
59 BM_CHECK(!running_);
60 return manual_time_used_;
61 }
62
63 private:
64 double ReadCpuTimerOfChoice() const {
65 if (measure_process_cpu_time) return ProcessCPUUsage();
66 return ThreadCPUUsage();
67 }
68
69 // should the thread, or the process, time be measured?
70 const bool measure_process_cpu_time;
71
72 bool running_ = false; // Is the timer running
73 double start_real_time_ = 0; // If running_
74 double start_cpu_time_ = 0; // If running_
75
76 // Accumulated time so far (does not contain current slice if running_)
77 double real_time_used_ = 0;
78 double cpu_time_used_ = 0;
79 // Manually set iteration time. User sets this with SetIterationTime(seconds).
80 double manual_time_used_ = 0;
81};
82
83} // namespace internal
84} // namespace benchmark
85
86#endif // BENCHMARK_THREAD_TIMER_H
87