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