cpp-stat-bench 0.24.0
Benchmark library with statistics for C++.
Loading...
Searching...
No Matches
sync_barrier.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
21
22#include <condition_variable> // IWYU pragma: keep
23#include <memory>
24#include <mutex>
25
27
28#if defined(_WIN32)
29// Windows
30#define STAT_BENCH_USE_WINDOWS_SYNC_BARRIER 1
32#elif defined(__linux__)
33// Linux
34#define STAT_BENCH_USE_PTHREAD_SYNC_BARRIER 1
36#endif
37
38namespace stat_bench {
39namespace util {
40
44class MutexSyncBarrier final : public ISyncBarrier {
45public:
51 explicit MutexSyncBarrier(std::size_t num_waiting_threads)
52 : num_waiting_threads_(num_waiting_threads) {
53 if (num_waiting_threads < 2U) {
54 throw StatBenchException(
55 "Invalid number of threads to wait in MutexSyncBarrier.");
56 }
57 }
58
62 void wait() override {
63 std::unique_lock<std::mutex> lock(mutex_);
64 if (num_remaining_threads_ == 0U) {
65 // This is the first thread to wait.
66 num_remaining_threads_ = num_waiting_threads_ - 1U;
67 cond_var_.wait(
68 lock, [this] { return num_remaining_threads_ == 0U; });
69 } else if (num_remaining_threads_ == 1U) {
70 // This is the last thread to wait.
71 num_remaining_threads_ = 0U;
72 lock.unlock();
73 cond_var_.notify_all();
74 } else {
75 --num_remaining_threads_;
76 cond_var_.wait(
77 lock, [this] { return num_remaining_threads_ == 0U; });
78 }
79 }
80
81 MutexSyncBarrier(const MutexSyncBarrier&) = delete;
82 MutexSyncBarrier(MutexSyncBarrier&&) = delete;
83 auto operator=(const MutexSyncBarrier&) = delete;
84 auto operator=(MutexSyncBarrier&&) = delete;
85
87 ~MutexSyncBarrier() override = default;
88
89private:
91 std::mutex mutex_{};
92
94 std::condition_variable cond_var_{};
95
97 std::size_t num_waiting_threads_;
98
100 std::size_t num_remaining_threads_{0};
101};
102
103auto create_mutex_sync_barrier(std::size_t num_waiting_threads)
104 -> std::shared_ptr<ISyncBarrier> {
105 return std::make_shared<MutexSyncBarrier>(num_waiting_threads);
106}
107
108auto create_sync_barrier(std::size_t num_waiting_threads)
109 -> std::shared_ptr<ISyncBarrier> {
110#if defined(STAT_BENCH_USE_WINDOWS_SYNC_BARRIER)
111 using Barrier = WindowsSyncBarrier;
112#elif defined(STAT_BENCH_USE_PTHREAD_SYNC_BARRIER)
113 using Barrier = PthreadSyncBarrier;
114#else
115 using Barrier = MutexSyncBarrier;
116#endif
117 return std::make_shared<Barrier>(num_waiting_threads);
118}
119
120} // namespace util
121} // namespace stat_bench
Interface of barriers to synchronize threads.
Class of barriers to synchronize threads using pthread library.
Class of barriers to synchronize threads using synchronization barriers in Windows.
Namespace of utility functions and classes.
auto create_mutex_sync_barrier(std::size_t num_waiting_threads) -> std::shared_ptr< ISyncBarrier >
Create a barrier to synchronize threads using a mutex.
auto create_sync_barrier(std::size_t num_waiting_threads) -> std::shared_ptr< ISyncBarrier >
Create a barrier to synchronize threads.
Namespace of stat_bench source codes.
Definition of PthreadSyncBarrier class. (Internal header.)
Definition of StatBenchException class.
Definition of SyncBarrier class.
Definition of WindowsSyncBarrier class. (Internal header.)