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