docs/semaphore_8hpp_source.html
| | Taskflow: A General-purpose Task-parallel Programming System |
Loading...
Searching...
No Matches
semaphore.hpp
1#pragma once
2
3#include <mutex>
4
5#include "declarations.hpp"
6#include "../utility/small_vector.hpp"
7
12
13namespace tf {
14
15// ----------------------------------------------------------------------------
16// Semaphore
17// ----------------------------------------------------------------------------
18
69
70friend class Node;
71friend class Executor;
72
73public:
74
82
93explicit Semaphore(size_t max_value);
94
98size_t value() const;
99
103size_t max_value() const;
104
108void reset();
109
113void reset(size_t new_max_value);
114
115private:
116
117mutable std::mutex _mtx;
118
119size_t _max_value{0};
120size_t _cur_value{0};
121
122 SmallVector<Node*> _waiters;
123
124bool _try_acquire_or_wait(Node*);
125
126void _release(SmallVector<Node*>&);
127};
128
129inline Semaphore::Semaphore(size_t max_value) :
130 _max_value(max_value),
131 _cur_value(max_value) {
132}
133
134inline bool Semaphore::_try_acquire_or_wait(Node* me) {
135 std::lock_guard<std::mutex> lock(_mtx);
136if(_cur_value > 0) {
137 --_cur_value;
138return true;
139 }
140else {
141 _waiters.push_back(me);
142return false;
143 }
144}
145
146inline void Semaphore::_release(SmallVector<Node*>& dst) {
147
148 std::lock_guard<std::mutex> lock(_mtx);
149
150if(_cur_value >= _max_value) {
151 TF_THROW("can't release the semaphore more than its maximum value: ", _max_value);
152 }
153
154 ++_cur_value;
155
156if(dst.empty()) {
157 dst.swap(_waiters);
158 }
159else {
160 dst.reserve(dst.size() + _waiters.size());
161 dst.insert(dst.end(), _waiters.begin(), _waiters.end());
162 _waiters.clear();
163 }
164}
165
166inline size_t Semaphore::max_value() const {
167return _max_value;
168}
169
170inline size_t Semaphore::value() const {
171 std::lock_guard<std::mutex> lock(_mtx);
172return _cur_value;
173}
174
175inline void Semaphore::reset() {
176 std::lock_guard<std::mutex> lock(_mtx);
177 _cur_value = _max_value;
178 _waiters.clear();
179}
180
181inline void Semaphore::reset(size_t new_max_value) {
182 std::lock_guard<std::mutex> lock(_mtx);
183 _cur_value = (_max_value = new_max_value);
184 _waiters.clear();
185}
186
187} // end of namespace tf. ---------------------------------------------------
188
size_t max_value() const
queries the maximum allowable value of this semaphore
Definition semaphore.hpp:166
Semaphore()=default
constructs a default semaphore
size_t value() const
queries the current counter value
Definition semaphore.hpp:170
void reset()
resets the semaphores to a clean state
Definition semaphore.hpp:175
class to define a vector optimized for small array
Definition small_vector.hpp:931
taskflow namespace
Definition small_vector.hpp:20