| #ifndef BENCHMARK_THREAD_MANAGER_H | |
| #define BENCHMARK_THREAD_MANAGER_H | |
| #include <atomic> | |
| #include "benchmark/benchmark.h" | |
| #include "mutex.h" | |
| namespace benchmark { | |
| namespace internal { | |
| class ThreadManager { | |
| public: | |
| explicit ThreadManager(int num_threads) | |
| : alive_threads_(num_threads), start_stop_barrier_(num_threads) {} | |
| Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) { | |
| return benchmark_mutex_; | |
| } | |
| bool StartStopBarrier() EXCLUDES(end_cond_mutex_) { | |
| return start_stop_barrier_.wait(); | |
| } | |
| void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) { | |
| start_stop_barrier_.removeThread(); | |
| if (--alive_threads_ == 0) { | |
| MutexLock lock(end_cond_mutex_); | |
| end_condition_.notify_all(); | |
| } | |
| } | |
| void WaitForAllThreads() EXCLUDES(end_cond_mutex_) { | |
| MutexLock lock(end_cond_mutex_); | |
| end_condition_.wait(lock.native_handle(), | |
| [this]() { return alive_threads_ == 0; }); | |
| } | |
| public: | |
| struct Result { | |
| IterationCount iterations = 0; | |
| double real_time_used = 0; | |
| double cpu_time_used = 0; | |
| double manual_time_used = 0; | |
| int64_t complexity_n = 0; | |
| std::string report_label_; | |
| std::string error_message_; | |
| bool has_error_ = false; | |
| UserCounters counters; | |
| }; | |
| GUARDED_BY(GetBenchmarkMutex()) Result results; | |
| private: | |
| mutable Mutex benchmark_mutex_; | |
| std::atomic<int> alive_threads_; | |
| Barrier start_stop_barrier_; | |
| Mutex end_cond_mutex_; | |
| Condition end_condition_; | |
| }; | |
| } // namespace internal | |
| } // namespace benchmark | |
| #endif // BENCHMARK_THREAD_MANAGER_H |