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 { ThreadTimer(bool measure_process_cpu_time_)11 explicit ThreadTimer(bool measure_process_cpu_time_) 12 : measure_process_cpu_time(measure_process_cpu_time_) {} 13 14 public: Create()15 static ThreadTimer Create() { 16 return ThreadTimer(/*measure_process_cpu_time_=*/false); 17 } CreateProcessCpuTime()18 static ThreadTimer CreateProcessCpuTime() { 19 return ThreadTimer(/*measure_process_cpu_time_=*/true); 20 } 21 22 // Called by each thread StartTimer()23 void StartTimer() { 24 running_ = true; 25 start_real_time_ = ChronoClockNow(); 26 start_cpu_time_ = ReadCpuTimerOfChoice(); 27 } 28 29 // Called by each thread StopTimer()30 void StopTimer() { 31 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 SetIterationTime(double seconds)41 void SetIterationTime(double seconds) { manual_time_used_ += seconds; } 42 running()43 bool running() const { return running_; } 44 45 // REQUIRES: timer is not running real_time_used()46 double real_time_used() { 47 CHECK(!running_); 48 return real_time_used_; 49 } 50 51 // REQUIRES: timer is not running cpu_time_used()52 double cpu_time_used() { 53 CHECK(!running_); 54 return cpu_time_used_; 55 } 56 57 // REQUIRES: timer is not running manual_time_used()58 double manual_time_used() { 59 CHECK(!running_); 60 return manual_time_used_; 61 } 62 63 private: ReadCpuTimerOfChoice()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