ladivic
Loading...
Searching...
No Matches
ldvc_atomic.hpp
Go to the documentation of this file.
1/*
2 * This file is part of the ladivic library.
3 * Copyright (c) 2024 Nathanne Isip
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24/**
25 *
26 * @file ldvc_atomic.hpp
27 * @brief Provides utilities for atomic operations with mutex protection in C++.
28 *
29 * This header file defines functions for performing atomic operations on `std::atomic` variables
30 * with the protection of a mutex. These functions ensure thread safety while allowing atomicity
31 * for operations such as incrementing, decrementing, bitwise operations, exchange, load, and store.
32 *
33 * @author Nathanne Isip
34 *
35 */
36#ifndef LDVC_ATOMIC_HPP
37#define LDVC_ATOMIC_HPP
38
39#include <atomic>
40#include <mutex>
41
42/**
43 *
44 * @brief Initializes an `std::atomic` variable with the specified
45 * initial value under the protection of a mutex.
46 *
47 * This function initializes an `std::atomic` variable `var` with
48 * the specified initial value `value` under the protection of the
49 * provided mutex `mutex`.
50 *
51 * @tparam T The type of the atomic variable.
52 *
53 * @param var The atomic variable to be initialized.
54 * @param mutex The mutex for thread safety.
55 * @param value The initial value for the atomic variable.
56 *
57 */
58template <typename T>
59void ldvc_atomic_create(std::atomic<T>& var, std::mutex& mutex, T value)
60{
61 std::lock_guard<std::mutex> lock(mutex);
62 var.store(value, std::memory_order_relaxed);
63}
64
65/**
66 *
67 * @brief Resets an `std::atomic` variable to its
68 * default-constructed value under the protection
69 * of a mutex.
70 *
71 * This function resets an `std::atomic` variable `var`
72 * to its default-constructed value under the protection of
73 * the provided mutex `mutex`.
74 *
75 * @tparam T The type of the atomic variable.
76 * @param var The atomic variable to be reset.
77 * @param mutex The mutex for thread safety.
78 */
79template<typename T>
80void ldvc_atomic_delete(std::atomic<T>& var, std::mutex& mutex)
81{
82 std::lock_guard<std::mutex> lock(mutex);
83 var.store(T{}, std::memory_order_relaxed);
84}
85
86/**
87 *
88 * @brief Atomically increments the value of an `std::atomic`
89 * variable by the specified amount under the protection of a mutex.
90 *
91 * This function atomically increments the value of an `std::atomic`
92 * variable `var` by the specified amount `arg` under the protection
93 * of the provided mutex `mutex`.
94 *
95 * @tparam T The type of the atomic variable.
96 *
97 * @param var The atomic variable to be incremented.
98 * @param mutex The mutex for thread safety.
99 * @param arg The amount by which to increment the atomic variable.
100 *
101 */
102template <typename T>
103void ldvc_atomic_inc(std::atomic<T>& var, std::mutex& mutex, T arg)
104{
105 std::lock_guard<std::mutex> lock(mutex);
106 var.fetch_add(arg, std::memory_order_relaxed);
107}
108
109/**
110 *
111 * @brief Atomically decrements the value of an `std::atomic`
112 * variable by the specified amount under the protection
113 * of a mutex.
114 *
115 * This function atomically decrements the value of an `std::atomic`
116 * variable `var` by the specified amount `arg` under the protection
117 * of the provided mutex `mutex`.
118 *
119 * @tparam T The type of the atomic variable.
120 *
121 * @param var The atomic variable to be decremented.
122 * @param mutex The mutex for thread safety.
123 * @param arg The amount by which to decrement the atomic variable.
124 *
125 */
126template <typename T>
127void ldvc_atomic_dec(std::atomic<T>& var, std::mutex& mutex, T arg)
128{
129 std::lock_guard<std::mutex> lock(mutex);
130 var.fetch_sub(arg, std::memory_order_relaxed);
131}
132
133/**
134 *
135 * @brief Performs a bitwise AND operation on an `std::atomic`
136 * variable with the specified value under the protection
137 * of a mutex.
138 *
139 * This function performs a bitwise AND operation on an `std::atomic`
140 * variable `var` with the specified value `arg` under the protection
141 * of the provided mutex `mutex`.
142 *
143 * @tparam T The type of the atomic variable.
144 *
145 * @param var The atomic variable to be bitwise ANDed.
146 * @param mutex The mutex for thread safety.
147 * @param arg The value for the bitwise AND operation.
148 *
149 */
150template <typename T>
151void ldvc_atomic_and(std::atomic<T>& var, std::mutex& mutex, T arg)
152{
153 std::lock_guard<std::mutex> lock(mutex);
154 var.fetch_and(arg, std::memory_order_relaxed);
155}
156
157/**
158 *
159 * @brief Performs a bitwise OR operation on an `std::atomic`
160 * variable with the specified value under the protection of a mutex.
161 *
162 * This function performs a bitwise OR operation on an `std::atomic`
163 * variable `var` with the specified value `arg` under the protection
164 * of the provided mutex `mutex`.
165 *
166 * @tparam T The type of the atomic variable.
167 *
168 * @param var The atomic variable to be bitwise ORed.
169 * @param mutex The mutex for thread safety.
170 * @param arg The value for the bitwise OR operation.
171 *
172 */
173template <typename T>
174void ldvc_atomic_or(std::atomic<T>& var, std::mutex& mutex, T arg)
175{
176 std::lock_guard<std::mutex> lock(mutex);
177 var.fetch_or(arg, std::memory_order_relaxed);
178}
179
180/**
181 *
182 * @brief Performs a bitwise XOR operation on an `std::atomic`
183 * variable with the specified value under the protection
184 * of a mutex.
185 *
186 * This function performs a bitwise XOR operation on an `std::atomic`
187 * variable `var` with the specified value `arg` under the protection
188 * of the provided mutex `mutex`.
189 *
190 * @tparam T The type of the atomic variable.
191 *
192 * @param var The atomic variable to be bitwise XORed.
193 * @param mutex The mutex for thread safety.
194 * @param arg The value for the bitwise XOR operation.
195 *
196 */
197template <typename T>
198void ldvc_atomic_xor(std::atomic<T>& var, std::mutex& mutex, T arg)
199{
200 std::lock_guard<std::mutex> lock(mutex);
201 var.fetch_xor(arg, std::memory_order_relaxed);
202}
203
204/**
205 * @brief Atomically exchanges the value of an `std::atomic` variable
206 * with a new value under the protection of a mutex.
207 *
208 * This function atomically exchanges the value of an `std::atomic`
209 * variable `var` with the specified new value `new_value`
210 * under the protection of the provided mutex `mutex`. It returns the
211 * previous value of the atomic variable.
212 *
213 * @tparam T The type of the atomic variable.
214 *
215 * @param var The atomic variable to be exchanged.
216 * @param mutex The mutex for thread safety.
217 * @param new_value The new value to be stored in the atomic variable.
218 *
219 * @return T The previous value of the atomic variable.
220 *
221 */
222template <typename T>
223T ldvc_atomic_exchange(std::atomic<T>& var, std::mutex& mutex, T new_value)
224{
225 std::lock_guard<std::mutex> lock(mutex);
226 return var.exchange(new_value, std::memory_order_relaxed);
227}
228
229/**
230 * @brief Atomically loads the value of an `std::atomic` variable
231 * under the protection of a mutex.
232 *
233 * This function atomically loads the value of an `std::atomic`
234 * variable `var` under the protection of the provided mutex `mutex`.
235 *
236 * @tparam T The type of the atomic variable.
237 *
238 * @param var The atomic variable to be loaded.
239 * @param mutex The mutex for thread safety.
240 *
241 * @return T The value of the atomic variable.
242 *
243 */
244template <typename T>
245T ldvc_atomic_load(const std::atomic<T>& var, std::mutex& mutex)
246{
247 std::lock_guard<std::mutex> lock(mutex);
248 return var.load(std::memory_order_relaxed);
249}
250
251/**
252 *
253 * @brief Atomically stores a new value in an `std::atomic`
254 * variable under the protection of a mutex.
255 *
256 * This function atomically stores the specified new value
257 * `new_value` in an `std::atomic` variable `var`
258 * under the protection of the provided mutex `mutex`.
259 *
260 * @tparam T The type of the atomic variable.
261 *
262 * @param var The atomic variable to be stored.
263 * @param mutex The mutex for thread safety.
264 * @param new_value The new value to be stored in the atomic variable.
265 *
266 */
267template <typename T>
268void ldvc_atomic_store(std::atomic<T>& var, std::mutex& mutex, T new_value)
269{
270 std::lock_guard<std::mutex> lock(mutex);
271 var.store(new_value, std::memory_order_relaxed);
272}
273
274#endif
void ldvc_atomic_inc(std::atomic< T > &var, std::mutex &mutex, T arg)
Atomically increments the value of an std::atomic variable by the specified amount under the protecti...
T ldvc_atomic_exchange(std::atomic< T > &var, std::mutex &mutex, T new_value)
Atomically exchanges the value of an std::atomic variable with a new value under the protection of a ...
void ldvc_atomic_dec(std::atomic< T > &var, std::mutex &mutex, T arg)
Atomically decrements the value of an std::atomic variable by the specified amount under the protecti...
void ldvc_atomic_create(std::atomic< T > &var, std::mutex &mutex, T value)
Initializes an std::atomic variable with the specified initial value under the protection of a mutex.
void ldvc_atomic_xor(std::atomic< T > &var, std::mutex &mutex, T arg)
Performs a bitwise XOR operation on an std::atomic variable with the specified value under the protec...
void ldvc_atomic_store(std::atomic< T > &var, std::mutex &mutex, T new_value)
Atomically stores a new value in an std::atomic variable under the protection of a mutex.
void ldvc_atomic_and(std::atomic< T > &var, std::mutex &mutex, T arg)
Performs a bitwise AND operation on an std::atomic variable with the specified value under the protec...
void ldvc_atomic_delete(std::atomic< T > &var, std::mutex &mutex)
Resets an std::atomic variable to its default-constructed value under the protection of a mutex.
T ldvc_atomic_load(const std::atomic< T > &var, std::mutex &mutex)
Atomically loads the value of an std::atomic variable under the protection of a mutex.
void ldvc_atomic_or(std::atomic< T > &var, std::mutex &mutex, T arg)
Performs a bitwise OR operation on an std::atomic variable with the specified value under the protect...