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