GCC Code Coverage Report


Directory: src/gate/
File: src/gate/cxx_synchronization.cpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 143 168 85.1%
Functions: 37 42 88.1%
Branches: 33 73 45.2%

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 #include "gate/synchronization.hpp"
30 #include "gate/exceptions.hpp"
31
32 namespace gate
33 {
34
35 3 Mutex::Mutex()
36 {
37 3 result_t result = gate_mutex_create(&this->impl);
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(result);
39 3 }
40
41 6 Mutex::~Mutex() noexcept
42 {
43 3 gate_mutex_destroy(&this->impl);
44 3 }
45
46 3 gate_mutex_t* Mutex::c_impl() const
47 {
48 3 return &this->impl;
49 }
50
51 5 void Mutex::acquire() const
52 {
53 5 result_t result = gate_mutex_acquire(&this->impl);
54
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATEXX_CHECK_ERROR(result);
55 5 }
56
57 5 result_t Mutex::release() const noexcept
58 {
59 5 result_t result = gate_mutex_release(&this->impl);
60 5 return result;
61 }
62
63
64
65
66 4 MutexLock::MutexLock(Mutex& mutex)
67 4 : impl(mutex)
68 {
69 4 impl.acquire();
70 4 }
71 8 MutexLock::~MutexLock() noexcept
72 {
73 4 impl.release();
74 4 }
75
76 3 gate_mutex_t* MutexLock::c_impl() const
77 {
78 3 return this->impl.c_impl();
79 }
80
81
82
83
84 1 Semaphore::Semaphore(uint32_t count)
85 {
86 1 result_t result = gate_semaphore_create(&this->impl, count);
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(result);
88 1 }
89 2 Semaphore::~Semaphore() noexcept
90 {
91 1 gate_semaphore_destroy(&this->impl);
92 1 }
93
94 2 void Semaphore::acquire()
95 {
96 2 result_t result = gate_semaphore_acquire(&this->impl);
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATEXX_CHECK_ERROR(result);
98 2 }
99 2 bool_t Semaphore::timedAcquire(uint32_t timeoutms)
100 {
101 2 result_t result = gate_semaphore_timed_acquire(&this->impl, timeoutms);
102
2/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 switch (result)
103 {
104 1 case GATE_RESULT_OK: return true;
105 1 case GATE_RESULT_TIMEOUT: break;
106 default:
107 {
108 GATEXX_CHECK_ERROR(result);
109 break;
110 }
111 }
112 1 return false;
113 }
114 3 void Semaphore::release()
115 {
116 3 result_t result = gate_semaphore_release(&this->impl);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(result);
118 3 }
119
120
121
122
123
124 3 SyncEvent::SyncEvent(bool autoreset)
125 {
126 3 result_t result = gate_syncevent_create(&this->impl, autoreset);
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(result);
128 3 }
129 6 SyncEvent::~SyncEvent() noexcept
130 {
131 3 gate_syncevent_destroy(&this->impl);
132 3 }
133
134 3 void SyncEvent::set()
135 {
136 3 result_t result = gate_syncevent_set(&this->impl);
137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(result);
138 3 }
139 2 void SyncEvent::reset()
140 {
141 2 result_t result = gate_syncevent_reset(&this->impl);
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATEXX_CHECK_ERROR(result);
143 2 }
144 2 void SyncEvent::wait()
145 {
146 2 result_t result = gate_syncevent_wait(&this->impl);
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATEXX_CHECK_ERROR(result);
148 2 }
149 4 bool_t SyncEvent::waitFor(uint32_t timeoutms)
150 {
151 4 result_t result = gate_syncevent_timed_wait(&this->impl, timeoutms);
152
2/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
4 switch (result)
153 {
154 1 case GATE_RESULT_OK: return true;
155 3 case GATE_RESULT_TIMEOUT: break;
156 default:
157 {
158 GATEXX_CHECK_ERROR(result);
159 break;
160 }
161 }
162 3 return false;
163 }
164
165
166
167 1 SyncCondition::SyncCondition()
168 {
169 1 result_t result = gate_synccondition_create(&this->impl);
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(result);
171 1 }
172 2 SyncCondition::~SyncCondition()
173 {
174 1 gate_synccondition_destroy(&this->impl);
175 1 }
176 gate_synccondition_t* SyncCondition::c_impl()
177 {
178 return &this->impl;
179 }
180
181 1 void SyncCondition::signalOne()
182 {
183 1 result_t result = gate_synccondition_signal_one(&this->impl);
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(result);
185 1 }
186 1 void SyncCondition::signalAll()
187 {
188 1 result_t result = gate_synccondition_signal_all(&this->impl);
189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(result);
190 1 }
191 void SyncCondition::wait(MutexLock& mutex)
192 {
193 result_t result = gate_synccondition_wait(&this->impl, mutex.c_impl());
194 GATEXX_CHECK_ERROR(result);
195 }
196 3 bool SyncCondition::waitFor(MutexLock& mutex, uint32_t milliseconds)
197 {
198 3 result_t result = gate_synccondition_timed_wait(&this->impl, mutex.c_impl(), milliseconds);
199
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 switch (result)
200 {
201 case GATE_RESULT_OK:
202 return true;
203 3 case GATE_RESULT_TIMEOUT:
204 3 break;
205 default:
206 GATEXX_RAISE_ERROR(result);
207 break;
208 }
209 3 return false;
210 }
211 1 bool SyncCondition::waitUntil(MutexLock& mutex, Time const& timeout_time)
212 {
213
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Time now = Time::now();
214 1 int64_t diffMicroseconds = timeout_time.timestamp - now.timestamp;
215
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (diffMicroseconds < 0) diffMicroseconds = 0;
216
217 1 uint32_t milliseconds = static_cast<uint32_t>((diffMicroseconds + 500) / 1000);
218
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return this->waitFor(mutex, milliseconds);
219 }
220 1 bool SyncCondition::waitUntil(MutexLock& mutex, TimeCounter const& timeout_time)
221 {
222
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TimeCounter now = TimeCounter::now();
223 1 int64_t microseconds = timeout_time.diff(now);
224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (microseconds < 0) microseconds = 0;
225 1 uint32_t milliseconds = static_cast<uint32_t>((microseconds + 500) / 1000);
226
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return this->waitFor(mutex, milliseconds);
227 }
228
229
230 2 FutureBase::FutureBase(size_t typeSize, gate_mem_copyctor_t cctor, gate_mem_dtor_t dtor)
231 {
232 2 result_t result = gate_future_create(&this->impl, typeSize, cctor, dtor);
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATEXX_CHECK_ERROR(result);
234 2 }
235 1 FutureBase::FutureBase(FutureBase const& src)
236 {
237 1 result_t result = gate_future_retain(&this->impl, &src.impl);
238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(result);
239 1 }
240 1 FutureBase& FutureBase::operator=(FutureBase const& src)
241 {
242
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (this != &src)
243 {
244 1 gate_future_t newimpl = NULL;
245
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 result_t result = gate_future_retain(&newimpl, &src.impl);
246
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_ERROR(result);
247
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_future_release(&this->impl);
248 1 this->impl = newimpl;
249 }
250 1 return *this;
251 }
252 6 FutureBase::~FutureBase() noexcept
253 {
254 3 gate_future_release(&this->impl);
255 3 }
256
257 4 bool FutureBase::hasValue() const noexcept
258 {
259 4 return gate_future_available(&this->impl);
260 }
261 result_t FutureBase::getResult() const noexcept
262 {
263 return gate_future_get_result(&this->impl);
264 }
265 4 void const* FutureBase::getData() const noexcept
266 {
267 4 return gate_future_get_data(&this->impl);
268 }
269 2 void FutureBase::set(result_t taskResult, void const* taskData)
270 {
271 2 result_t result = gate_future_set_result(&this->impl, taskResult, taskData);
272
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 GATEXX_CHECK_ERROR(result);
273 1 }
274 3 void FutureBase::wait()
275 {
276 3 result_t result = gate_future_await(&this->impl);
277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(result);
278 3 }
279 1 bool FutureBase::waitFor(uint32_t timeoutMs)
280 {
281 1 result_t result = gate_future_await_timed(&this->impl, timeoutMs);
282
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (result == GATE_RESULT_TIMEOUT)
283 {
284 1 return false;
285 }
286 GATEXX_CHECK_ERROR(result);
287 return true;
288 }
289
290 1 bool FutureBase::empty() const noexcept
291 {
292 1 return !this->hasValue();
293 }
294 bool FutureBase::operator!() const noexcept
295 {
296 return !this->hasValue();
297 }
298
299 gate_future_t const* FutureBase::c_impl() const
300 {
301 return &this->impl;
302 }
303 1 gate_future_t* FutureBase::c_impl()
304 {
305 1 return &this->impl;
306 }
307
308 } // end of namespace gate
309