Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
synchronization.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
15#include <mutex>
16#include <condition_variable>
17#include <atomic>
18#include <functional>
19
20#ifdef HAS_STD_LATCH
21#include <latch>
22#include <barrier>
23#endif
24
25namespace kcenon::thread {
26
27#ifdef HAS_STD_LATCH
28 // C++20: Use standard library implementations
29 using std::latch;
30 using std::barrier;
31#else
39 class latch {
40 public:
45 explicit latch(std::ptrdiff_t count)
46 : count_(count) {}
47
52 void count_down(std::ptrdiff_t n = 1) {
53 std::unique_lock<std::mutex> lock(mutex_);
54 count_ -= n;
55 if (count_ <= 0) {
56 cv_.notify_all();
57 }
58 }
59
64 bool try_wait() const noexcept {
65 std::unique_lock<std::mutex> lock(mutex_);
66 return count_ <= 0;
67 }
68
72 void wait() const {
73 std::unique_lock<std::mutex> lock(mutex_);
74 cv_.wait(lock, [this] { return count_ <= 0; });
75 }
76
81 void arrive_and_wait(std::ptrdiff_t n = 1) {
82 count_down(n);
83 wait();
84 }
85
86 private:
87 mutable std::mutex mutex_;
88 mutable std::condition_variable cv_;
89 std::ptrdiff_t count_;
90 };
91
100 template<typename CompletionFunction = std::function<void()>>
101 class barrier {
102 public:
108 explicit barrier(std::ptrdiff_t count,
109 CompletionFunction completion = [](){})
110 : threshold_(count)
111 , count_(count)
112 , generation_(0)
113 , completion_(std::move(completion)) {}
114
124 std::unique_lock<std::mutex> lock(mutex_);
125 auto gen = generation_;
126
127 if (--count_ == 0) {
128 // Last thread to arrive
129 generation_++;
131
132 // Call completion function (if provided)
133 if constexpr (!std::is_same_v<CompletionFunction, std::function<void()>>) {
134 completion_();
135 } else if (completion_) {
136 completion_();
137 }
138
139 cv_.notify_all();
140 } else {
141 // Wait for all threads to arrive
142 cv_.wait(lock, [this, gen] { return gen != generation_; });
143 }
144 }
145
153 std::unique_lock<std::mutex> lock(mutex_);
154 --threshold_;
156 }
157
158 private:
159 mutable std::mutex mutex_;
160 mutable std::condition_variable cv_;
161 std::ptrdiff_t threshold_; // Total number of threads
162 std::ptrdiff_t count_; // Remaining threads in current phase
163 std::size_t generation_; // Current phase number
164 CompletionFunction completion_;
165 };
166
167#endif // HAS_STD_LATCH
168
169} // namespace kcenon::thread
C++17-compatible barrier implementation.
void arrive_and_drop()
Decrements the counter without blocking.
barrier(std::ptrdiff_t count, CompletionFunction completion=[](){})
Constructs a barrier for the given number of threads.
void arrive_and_wait()
Arrives at the barrier and blocks until all threads arrive.
std::condition_variable cv_
CompletionFunction completion_
C++17-compatible latch implementation.
void count_down(std::ptrdiff_t n=1)
Decrements the counter in a non-blocking manner.
void wait() const
Blocks until the counter reaches zero.
latch(std::ptrdiff_t count)
Constructs a latch with the given count.
bool try_wait() const noexcept
Tests if the internal counter equals zero.
void arrive_and_wait(std::ptrdiff_t n=1)
Decrements the counter and blocks until it reaches zero.
std::condition_variable cv_
Core threading foundation of the thread system library.
Definition thread_impl.h:17
STL namespace.