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 | 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&: lock.native_handle(), |
36 | p: [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 skip_message_; |
47 | internal::Skipped skipped_ = internal::NotSkipped; |
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 |