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