GCC Code Coverage Report


Directory: src/gate/
File: src/gate/synchronization.hpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 28 28 100.0%
Functions: 9 9 100.0%
Branches: 5 10 50.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 /** @file
30 * @brief Synchronization primitives (mutex, semaphore, conditions, futures)
31 * @ingroup gatecore_cpp
32 */
33
34
35 #ifndef GATE_SYNCHRONIZATION_HPP_INCLUDED
36 #define GATE_SYNCHRONIZATION_HPP_INCLUDED
37
38 #include "gate/gate_core_api.hpp"
39 #include "gate/gatetypes.hpp"
40 #include "gate/times.hpp"
41 #include "gate/synchronization.h"
42 #include "gate/memalloc.hpp"
43 #include "gate/debugging.h"
44
45 namespace gate
46 {
47
48 /// @brief
49 class GATE_CORE_CPP_API Mutex : private NonCopyable
50 {
51 public:
52 Mutex();
53 ~Mutex() noexcept;
54
55 void acquire() const;
56 result_t release() const noexcept;
57
58 gate_mutex_t* c_impl() const;
59
60 private:
61 mutable gate_mutex_t impl;
62 };
63
64
65 /// @brief
66 class GATE_CORE_CPP_API MutexLock : private NonCopyable
67 {
68 public:
69 MutexLock(Mutex& mutex);
70 ~MutexLock() noexcept;
71
72 gate_mutex_t* c_impl() const;
73
74 private:
75 Mutex const& impl;
76 };
77
78
79 /// @brief
80 class GATE_CORE_CPP_API Semaphore : private NonCopyable
81 {
82 public:
83 Semaphore(uint32_t count);
84 ~Semaphore() noexcept;
85
86 void acquire();
87 bool_t timedAcquire(uint32_t timeoutms);
88 void release();
89
90 gate_semaphore_t* c_impl();
91
92 private:
93 gate_semaphore_t impl;
94 };
95
96
97 /// @brief
98 class GATE_CORE_CPP_API SyncEvent : private NonCopyable
99 {
100 public:
101 SyncEvent(bool autoreset = false);
102 ~SyncEvent() noexcept;
103
104 gate_syncevent_t* c_impl();
105
106 void set();
107 void reset();
108 void wait();
109 bool_t waitFor(uint32_t timeoutms);
110
111 template<class DURATION>
112 4 bool waitFor(DURATION const& duration)
113 {
114
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 time::Milliseconds ms = time::duration_cast<time::Milliseconds>(duration);
115
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 return this->waitFor(static_cast<uint32_t>(ms.value()));
116 }
117
118 private:
119 gate_syncevent_t impl;
120 };
121
122
123 /// @brief
124 class GATE_CORE_CPP_API SyncCondition : private NonCopyable
125 {
126 public:
127 SyncCondition();
128 ~SyncCondition();
129
130 gate_synccondition_t* c_impl();
131
132 void signalOne();
133 void signalAll();
134 void wait(MutexLock& mutex);
135 bool waitFor(MutexLock& mutex, uint32_t milliseconds);
136 bool waitUntil(MutexLock& mutex, Time const& timeout_time);
137 bool waitUntil(MutexLock& mutex, TimeCounter const& timeout_time);
138
139 template<class DURATION>
140 bool waitFor(MutexLock& mutex, DURATION const& duration)
141 {
142 time::Milliseconds ms = time::duration_cast<time::Milliseconds>(duration);
143 return this->waitFor(mutex, static_cast<uint32_t>(ms.value()));
144 }
145
146 private:
147 gate_synccondition_t impl;
148 };
149
150
151 /// @brief
152 class GATE_CORE_CPP_API FutureBase : public SafeBoolBase<FutureBase>
153 {
154 public:
155 FutureBase(size_t typeSize, gate_mem_copyctor_t cctor = NULL, gate_mem_dtor_t dtor = NULL);
156 FutureBase(FutureBase const& src);
157 FutureBase& operator=(FutureBase const& src);
158 ~FutureBase() noexcept;
159
160 bool hasValue() const noexcept;
161 result_t getResult() const noexcept;
162 void const* getData() const noexcept;
163 void set(result_t result, void const* data);
164 void wait();
165 bool waitFor(uint32_t timeoutMs);
166
167 template<class DURATION>
168 1 bool waitFor(DURATION const& duration)
169 {
170
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 time::Milliseconds ms = time::duration_cast<time::Milliseconds>(duration);
171
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 return this->waitFor(static_cast<uint32_t>(ms.value()));
172 }
173
174
175 bool empty() const noexcept;
176 bool operator!() const noexcept;
177
178 gate_future_t* c_impl();
179 gate_future_t const* c_impl() const;
180
181 private:
182 gate_future_t impl;
183 };
184
185
186 /// @brief
187 /// @tparam T
188 template<class T>
189 class GATE_CORE_CPP_API Future : private FutureBase
190 {
191 public:
192 typedef T value_t;
193 typedef Future<T> self_t;
194
195 2 Future()
196 2 : FutureBase(sizeof(value_t), &TypeFunctions<value_t>::copyConstruct, &TypeFunctions<value_t>::destruct)
197 {
198 2 }
199 1 Future(self_t const& src)
200 1 : FutureBase(src)
201 {
202 1 }
203 1 self_t& operator=(self_t const& src)
204 {
205
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (this != &src)
206 {
207 1 FutureBase::operator=(src);
208 }
209 1 return *this;
210 }
211 3 ~Future() noexcept
212 {
213 3 }
214
215 using FutureBase::hasValue;
216 using FutureBase::empty;
217 using FutureBase::operator!;
218 using FutureBase::wait;
219 using FutureBase::waitFor;
220 using FutureBase::c_impl;
221
222
223 4 value_t const* getData() const noexcept
224 {
225 4 return static_cast<value_t const*>(FutureBase::getData());
226 }
227 2 void set(result_t result, value_t const& value)
228 {
229 2 FutureBase::set(result, static_cast<void const*>(&value));
230 1 }
231
232 2 value_t const& value()
233 {
234 2 this->wait();
235 2 value_t const* ptrValue = this->getData();
236 2 GATE_DEBUG_ASSERT(ptrValue);
237 2 return *ptrValue;
238 }
239 };
240
241 } // end of namespace gate
242
243 #endif
244