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 error_message_;
47 bool has_error_ = false;
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