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 9namespace benchmark { 10namespace internal { 11 12class ThreadManager { 13 public: 14 explicit ThreadManager(int num_threads) 15 : alive_threads_(num_threads), start_stop_barrier_(num_threads) {} 16 17 Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) { 18 return benchmark_mutex_; 19 } 20 21 bool StartStopBarrier() EXCLUDES(end_cond_mutex_) { 22 return start_stop_barrier_.wait(); 23 } 24 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 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 struct Result { 40 IterationCount iterations = 0; 41 double real_time_used = 0; 42 double cpu_time_used = 0; 43 double manual_time_used = 0; 44 int64_t complexity_n = 0; 45 std::string report_label_; 46 std::string skip_message_; 47 internal::Skipped skipped_ = internal::NotSkipped; 48 UserCounters counters; 49 }; 50 GUARDED_BY(GetBenchmarkMutex()) Result results; 51 52 private: 53 mutable Mutex benchmark_mutex_; 54 std::atomic<int> alive_threads_; 55 Barrier start_stop_barrier_; 56 Mutex end_cond_mutex_; 57 Condition end_condition_; 58}; 59 60} // namespace internal 61} // namespace benchmark 62 63#endif // BENCHMARK_THREAD_MANAGER_H 64