1 #ifndef BENCHMARK_THREAD_MANAGER_H 2 #define BENCHMARK_THREAD_MANAGER_H 3 4 #include <atomic> 5 6 #include "benchmark/benchmark.h" 7 #include "mutex.h" 8 9 namespace benchmark { 10 namespace internal { 11 12 class ThreadManager { 13 public: ThreadManager(int num_threads)14 ThreadManager(int num_threads) 15 : alive_threads_(num_threads), start_stop_barrier_(num_threads) {} 16 GetBenchmarkMutex()17 Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) { 18 return benchmark_mutex_; 19 } 20 StartStopBarrier()21 bool StartStopBarrier() EXCLUDES(end_cond_mutex_) { 22 return start_stop_barrier_.wait(); 23 } 24 NotifyThreadComplete()25 void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) { 26 start_stop_barrier_.removeThread(); 27 if (--alive_threads_ == 0) { 28 MutexLock lock(end_cond_mutex_); 29 end_condition_.notify_all(); 30 } 31 } 32 WaitForAllThreads()33 void WaitForAllThreads() EXCLUDES(end_cond_mutex_) { 34 MutexLock lock(end_cond_mutex_); 35 end_condition_.wait(lock.native_handle(), 36 [this]() { return alive_threads_ == 0; }); 37 } 38 39 public: 40 struct Result { 41 int64_t iterations = 0; 42 double real_time_used = 0; 43 double cpu_time_used = 0; 44 double manual_time_used = 0; 45 int64_t complexity_n = 0; 46 std::string report_label_; 47 std::string error_message_; 48 bool has_error_ = false; 49 UserCounters counters; 50 }; 51 GUARDED_BY(GetBenchmarkMutex()) Result results; 52 53 private: 54 mutable Mutex benchmark_mutex_; 55 std::atomic<int> alive_threads_; 56 Barrier start_stop_barrier_; 57 Mutex end_cond_mutex_; 58 Condition end_condition_; 59 }; 60 61 } // namespace internal 62 } // namespace benchmark 63 64 #endif // BENCHMARK_THREAD_MANAGER_H 65