Home | History | Annotate | Download | only in src
      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:
     14   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  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