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 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 IterationCount 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