• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   explicit 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   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