GCC Code Coverage Report


Directory: src/gate/
File: src/gate/atomics.hpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 15 15 100.0%
Functions: 6 6 100.0%
Branches: 0 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 Atomic integer and pointer operations
31 * @ingroup gatecore_cpp
32 */
33
34 #ifndef GATE_ATOMICS_HPP_INCLUDED
35 #define GATE_ATOMICS_HPP_INCLUDED
36
37 #include "gate/gate_core_api.hpp"
38 #include "gate/atomics.h"
39 #include "gate/gatetypes.hpp"
40 #include "gate/results.hpp"
41 #include "gate/exceptions.hpp"
42
43 namespace gate
44 {
45
46 class GATE_CORE_CPP_API AtomicFlag : private NonCopyable ///< Atomic boolean flag
47 {
48 public:
49 AtomicFlag(bool init = false) noexcept;
50 ~AtomicFlag() noexcept;
51
52 void clear() noexcept; ///< clears atomic flag (set to false)
53 bool_t set() noexcept; ///< set atomic flag (set to true) and returns previous state
54
55 private:
56 gate_atomic_flag_t impl;
57 };
58
59 class GATE_CORE_CPP_API AtomicInt ///< Atomic 32-bit integer
60 {
61 public:
62 AtomicInt(int32_t init = 0) noexcept; ///< Initialize atomic integer
63 AtomicInt(AtomicInt const& src) noexcept;
64 AtomicInt& operator=(AtomicInt const& src) noexcept;
65 ~AtomicInt() noexcept;
66
67 int32_t get() const noexcept; ///< Returns value of atomic integer
68 int32_t set(int32_t newvalue) noexcept; ///< Updates atomic integer to a new value and returns it previous value
69 int32_t changeIf(int32_t comparand, int32_t newvalue) noexcept; ///< Compares atomic integer with \p comparand and set its to \p newvalue if they match, returns previous value
70 bool_t updateIf(int32_t fromvalue, int32_t tovalue) noexcept; ///< Returns true if update from \p fromvalue to \p tovalue was successful
71
72 int32_t operator++() noexcept; ///< Increments atomic integer and returns its current value
73 int32_t operator++(int) noexcept; ///< Increments atomic integer and returns its previous value
74 int32_t operator--() noexcept; ///< Decrements atomic integer and returns its current value
75 int32_t operator--(int) noexcept; //< Decrements atomic integer and returns its previous value
76
77 int32_t operator+=(int32_t value) noexcept; ///< Adds number to atomic integer and returns its updated value
78 int32_t operator-=(int32_t value) noexcept; ///< Substracts number to atomic integer and returns its updated value
79
80 private:
81 gate_atomic_int_t impl;
82 };
83
84 class GATE_CORE_CPP_API AtomicInt64 ///< Atomic 64-bit integer
85 {
86 public:
87 AtomicInt64(int64_t init = 0) noexcept; ///< Initialize atomic integer
88 AtomicInt64(AtomicInt64 const& src) noexcept;
89 AtomicInt64& operator=(AtomicInt64 const& src) noexcept;
90 ~AtomicInt64() noexcept;
91
92 int64_t get() const noexcept; ///< Returns value of atomic integer
93 int64_t set(int64_t newvalue) noexcept; ///< Updates atomic integer to a new value and returns it previous value
94 int64_t changeIf(int64_t comparand, int64_t newvalue) noexcept; ///< Compares atomic integer with \p comparand and set its to \p newvalue if they match, returns previous value
95
96 int64_t operator++() noexcept; ///< Increments atomic integer and returns its current value
97 int64_t operator++(int) noexcept; ///< Increments atomic integer and returns its previous value
98 int64_t operator--() noexcept; ///< Decrements atomic integer and returns its current value
99 int64_t operator--(int) noexcept; ///< Decrements atomic integer and returns its previous value
100
101 int64_t operator+=(int64_t value) noexcept; ///< Adds number to atomic integer and returns its updated value
102 int64_t operator-=(int64_t value) noexcept; ///< Substracts number to atomic integer and returns its updated value
103
104 private:
105 gate_atomic_int64_t impl;
106 };
107
108 class GATE_CORE_CPP_API AtomicPointer ///< Atomic void* pointer
109 {
110 public:
111 AtomicPointer(void* init = NULL) noexcept; ///< Atomic pointer/address
112 AtomicPointer(AtomicPointer const& src) noexcept;
113 AtomicPointer& operator=(AtomicPointer const& src) noexcept;
114 ~AtomicPointer() noexcept;
115
116 void* get() const noexcept; ///< Returns value of atomic pointer
117 void* set(void* newvalue) noexcept; ///< Updates atomic pointer to a new value and returns it previous value
118 void* changeIf(void* comparand, void* newvalue) noexcept; ///< Updates atomic pointer to \p newvalue only if its original value was equal to \p comparand, returns original value of atomic pointer
119
120 private:
121 gate_atomic_ptr_t impl;
122 };
123
124 template <class T>
125 class GATE_CORE_CPP_API AtomicPtr ///< Template class for typed atomic pointer
126 {
127 private:
128 AtomicPointer impl;
129
130 public:
131 1 AtomicPtr(T* init = NULL) noexcept ///< Initializes atomic pointer
132 1 : impl(static_cast<void*>(init))
133 {
134 1 }
135 1 AtomicPtr(AtomicPtr& src) noexcept
136 1 : impl(static_cast<void*>(src.get()))
137 {
138 1 }
139 1 AtomicPtr& operator=(AtomicPtr const& src) noexcept
140 {
141 1 this->impl.set(src.impl.get());
142 1 return *this;
143 }
144
145 5 T* get() const noexcept ///< Returns current value of atomic pointer
146 {
147 5 return static_cast<T*>(this->impl.get());
148 }
149 2 T* set(T* newvalue) noexcept ///< Updates value of atomic pointer
150 {
151 2 return static_cast<T*>(this->impl.set(static_cast<void*>(newvalue)));
152 }
153 2 T* changeIf(T* comparand, T* newvalue) noexcept ///< updates atomic pointer to \p newvalue only if its original value equals \p comparand, returns original atomic pointer value
154 {
155 2 return static_cast<T*>(this->impl.changeIf(static_cast<void*>(comparand), static_cast<void*>(newvalue)));
156 }
157
158 T* operator->() noexcept ///< Access member of type accessed by atomic pointer
159 {
160 T* ptr = this->get();
161 if (ptr == NULL)
162 {
163 GATEXX_RAISE_ERROR(results::NullPointer);
164 }
165 return ptr;
166 }
167 T& operator*() noexcept ///< Dereferences atomic pointer
168 {
169 T* ptr = this->get();
170 if (ptr == NULL)
171 {
172 GATEXX_RAISE_ERROR(results::NullPointer);
173 }
174 return *ptr;
175 }
176 };
177
178 class GATE_CORE_CPP_API AtomicMutex : private NonCopyable ///< Non-recursive atomic mutex
179 {
180 public:
181 AtomicMutex() noexcept;
182 ~AtomicMutex() noexcept;
183
184 gate_atomic_lock_t* c_impl() noexcept;
185
186 void lock() noexcept; ///< Acquires mutex lock
187 bool lock(uint32_t spinCount) noexcept; ///< Try to acquire mutex lock, but cancel with false if spin-count is reached with lock
188 void unlock() noexcept; ///< Release mutex lock
189
190 private:
191 gate_atomic_lock_t impl;
192 };
193
194 class GATE_CORE_CPP_API AtomicLock : private NonCopyable ///< Atomic RAII mutex-lock
195 {
196 public:
197 AtomicLock(AtomicMutex& mtx) noexcept; ///< Acquires mutex lock
198 AtomicLock(gate_atomic_lock_t& ref_mtx) noexcept;
199 ~AtomicLock() noexcept; ///< Release mutex lock
200
201 private:
202 gate_atomic_lock_t* mutex;
203 };
204
205 class GATE_CORE_CPP_API AtomicRecursiveMutex : private NonCopyable ///< Recursive atomic mutex
206 {
207 public:
208 AtomicRecursiveMutex() noexcept; ///< Acquires mutex lock
209 ~AtomicRecursiveMutex() noexcept;
210
211 gate_atomic_rlock_t* c_impl() noexcept;
212
213 void lock() noexcept; ///< Acquires mutex lock
214 bool lock(uint32_t spinCount) noexcept; ///< Try to acquire mutex lock, but cancel with false if spin-count is reached with lock
215 void unlock() noexcept; ///< Release mutex lock
216
217 private:
218 gate_atomic_rlock_t impl;
219 };
220
221 class GATE_CORE_CPP_API AtomicRecursiveLock : private NonCopyable
222 {
223 public:
224 AtomicRecursiveLock(AtomicRecursiveMutex& mtx) noexcept;
225 AtomicRecursiveLock(gate_atomic_rlock_t& ref_mtx) noexcept;
226 ~AtomicRecursiveLock() noexcept;
227
228 private:
229 gate_atomic_rlock_t* mutex;
230 };
231
232 class GATE_CORE_CPP_API AtomicCallOnce : private NonCopyable
233 {
234 public:
235 AtomicCallOnce() noexcept;
236 ~AtomicCallOnce() noexcept;
237 void operator()(void (*func)(void));
238
239 private:
240 gate_atomic_flag_t state;
241 };
242
243 class GATE_CORE_CPP_API AtomicCallOnceEx : private NonCopyable
244 {
245 public:
246 AtomicCallOnceEx() noexcept;
247 ~AtomicCallOnceEx() noexcept;
248 void operator()(void (*func)(void));
249
250 private:
251 gate_atomic_flag_t state;
252 };
253
254 } // end of namespace gate
255
256 #endif
257