ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
atomic.c
Go to the documentation of this file.
1
16#include <stdatomic.h>
17#include <ascii-chat/atomic.h>
19
20// ============================================================================
21// bool Implementation Functions
22// ============================================================================
23
25 if (!a)
26 return false;
27 return (bool)atomic_load((const _Atomic(uint64_t) *)&a->impl);
28}
29
31 if (!a)
32 return;
33 atomic_store((_Atomic(uint64_t) *)&a->impl, value);
34}
35
36bool atomic_cas_bool_impl(atomic_t *a, bool *expected, bool new_value) {
37 if (!a || !expected)
38 return false;
39 uint64_t exp = (uint64_t)*expected;
40 bool success = atomic_compare_exchange_strong((_Atomic(uint64_t) *)&a->impl, &exp, (uint64_t)new_value);
41 *expected = (bool)exp;
42 return success;
43}
44
45// ============================================================================
46// int Implementation Functions
47// ============================================================================
48
50 if (!a)
51 return 0;
52 return (int)(int32_t)atomic_load((const _Atomic(uint64_t) *)&a->impl);
53}
54
56 if (!a)
57 return;
58 atomic_store((_Atomic(uint64_t) *)&a->impl, value);
59}
60
61int atomic_fetch_add_int_impl(atomic_t *a, int64_t delta) {
62 if (!a)
63 return 0;
64 return (int)(int32_t)atomic_fetch_add((_Atomic(uint64_t) *)&a->impl, (uint64_t)delta);
65}
66
67int atomic_fetch_sub_int_impl(atomic_t *a, int64_t delta) {
68 if (!a)
69 return 0;
70 return (int)(int32_t)atomic_fetch_sub((_Atomic(uint64_t) *)&a->impl, (uint64_t)delta);
71}
72
73// ============================================================================
74// uint64_t Implementation Functions
75// ============================================================================
76
78 if (!a)
79 return 0;
80 return atomic_load((const _Atomic(uint64_t) *)&a->impl);
81}
82
84 if (!a)
85 return;
86 atomic_store((_Atomic(uint64_t) *)&a->impl, value);
87}
88
90 if (!a)
91 return 0;
92 return atomic_fetch_add((_Atomic(uint64_t) *)&a->impl, delta);
93}
94
96 if (!a)
97 return 0;
98 return atomic_fetch_sub((_Atomic(uint64_t) *)&a->impl, delta);
99}
100
101bool atomic_cas_u64_impl(atomic_t *a, uint64_t *expected, uint64_t new_value) {
102 if (!a || !expected)
103 return false;
104 return atomic_compare_exchange_strong((_Atomic(uint64_t) *)&a->impl, expected, new_value);
105}
106
107bool atomic_cas_int_impl(atomic_t *a, int *expected, int new_value) {
108 if (!a || !expected)
109 return false;
110 uint64_t expected_u64 = (uint64_t)(int64_t)*expected;
111 bool result =
112 atomic_compare_exchange_strong((_Atomic(uint64_t) *)&a->impl, &expected_u64, (uint64_t)(int64_t)new_value);
113 *expected = (int)(int32_t)expected_u64;
114 return result;
115}
116
117// ============================================================================
118// Pointer Implementation Functions
119// ============================================================================
120
122 if (!a)
123 return NULL;
124 return atomic_load((const _Atomic(void *) *)&a->impl);
125}
126
127void atomic_ptr_store_impl(atomic_ptr_t *a, void *value) {
128 if (!a)
129 return;
130 atomic_store((_Atomic(void *) *)&a->impl, value);
131}
132
133bool atomic_ptr_cas_impl(atomic_ptr_t *a, void **expected, void *new_value) {
134 if (!a || !expected)
135 return false;
136 return atomic_compare_exchange_strong((_Atomic(void *) *)&a->impl, expected, new_value);
137}
138
139void *atomic_ptr_exchange_impl(atomic_ptr_t *a, void *new_value) {
140 if (!a)
141 return NULL;
142 return atomic_exchange((_Atomic(void *) *)&a->impl, new_value);
143}
144
145bool atomic_exchange_bool_impl(atomic_t *a, bool new_value) {
146 if (!a)
147 return false;
148 return (bool)atomic_exchange((_Atomic(uint64_t) *)&a->impl, (uint64_t)new_value);
149}
150
151int atomic_exchange_int_impl(atomic_t *a, int new_value) {
152 if (!a)
153 return 0;
154 return (int)(int32_t)atomic_exchange((_Atomic(uint64_t) *)&a->impl, (uint64_t)(int32_t)new_value);
155}
156
158 if (!a)
159 return 0;
160 return atomic_exchange((_Atomic(uint64_t) *)&a->impl, new_value);
161}
162
163// ============================================================================
164// Debug Build: Wrapper Functions with Hooks
165// ============================================================================
166
167#ifndef NDEBUG
168
170 if (!a)
171 return false;
172 bool result = (bool)atomic_load((const _Atomic(uint64_t) *)&a->impl);
174 return result;
175}
176
177void atomic_store_bool(atomic_t *a, bool value) {
178 if (!a)
179 return;
180 atomic_store((_Atomic(uint64_t) *)&a->impl, (uint64_t)value);
182}
183
184bool atomic_cas_bool(atomic_t *a, bool *expected, bool new_value) {
185 if (!a || !expected)
186 return false;
187 uint64_t exp = (uint64_t)*expected;
188 bool success = atomic_compare_exchange_strong((_Atomic(uint64_t) *)&a->impl, &exp, (uint64_t)new_value);
189 *expected = (bool)exp;
190 atomic_on_cas(a, success);
191 return success;
192}
193
195 if (!a)
196 return 0;
197 int result = (int)(int32_t)atomic_load((const _Atomic(uint64_t) *)&a->impl);
199 return result;
200}
201
202void atomic_store_int(atomic_t *a, int value) {
203 if (!a)
204 return;
205 atomic_store((_Atomic(uint64_t) *)&a->impl, (uint64_t)(int32_t)value);
207}
208
209int atomic_fetch_add_int(atomic_t *a, int delta) {
210 if (!a)
211 return 0;
212 int result = (int)(int32_t)atomic_fetch_add((_Atomic(uint64_t) *)&a->impl, (uint64_t)(int64_t)delta);
214 return result;
215}
216
217int atomic_fetch_sub_int(atomic_t *a, int delta) {
218 if (!a)
219 return 0;
220 int result = (int)(int32_t)atomic_fetch_sub((_Atomic(uint64_t) *)&a->impl, (uint64_t)(int64_t)delta);
222 return result;
223}
224
225bool atomic_cas_int(atomic_t *a, int *expected, int new_value) {
226 if (!a || !expected)
227 return false;
228 bool success = atomic_cas_int_impl(a, expected, new_value);
229 atomic_on_cas(a, success);
230 return success;
231}
232
234 if (!a)
235 return 0;
236 uint64_t result = atomic_load((const _Atomic(uint64_t) *)&a->impl);
238 return result;
239}
240
242 if (!a)
243 return;
244 atomic_store((_Atomic(uint64_t) *)&a->impl, value);
246}
247
249 if (!a)
250 return 0;
251 uint64_t result = atomic_fetch_add((_Atomic(uint64_t) *)&a->impl, delta);
253 return result;
254}
255
257 if (!a)
258 return 0;
259 uint64_t result = atomic_fetch_sub((_Atomic(uint64_t) *)&a->impl, delta);
261 return result;
262}
263
264bool atomic_cas_u64(atomic_t *a, uint64_t *expected, uint64_t new_value) {
265 if (!a || !expected)
266 return false;
267 bool success = atomic_compare_exchange_strong((_Atomic(uint64_t) *)&a->impl, expected, new_value);
268 atomic_on_cas(a, success);
269 return success;
270}
271
273 if (!a)
274 return NULL;
275 void *result = atomic_load((const _Atomic(void *) *)&a->impl);
277 return result;
278}
279
280void atomic_ptr_store(atomic_ptr_t *a, void *value) {
281 if (!a)
282 return;
283 atomic_store((_Atomic(void *) *)&a->impl, value);
285}
286
287bool atomic_ptr_cas(atomic_ptr_t *a, void **expected, void *new_value) {
288 if (!a || !expected)
289 return false;
290 bool success = atomic_compare_exchange_strong((_Atomic(void *) *)&a->impl, expected, new_value);
291 atomic_ptr_on_cas(a, success);
292 return success;
293}
294
295void *atomic_ptr_exchange(atomic_ptr_t *a, void *new_value) {
296 if (!a)
297 return NULL;
298 void *result = atomic_exchange((_Atomic(void *) *)&a->impl, new_value);
300 return result;
301}
302
303bool atomic_exchange_bool(atomic_t *a, bool new_value) {
304 if (!a)
305 return false;
306 bool result = (bool)atomic_exchange((_Atomic(uint64_t) *)&a->impl, (uint64_t)new_value);
308 return result;
309}
310
311int atomic_exchange_int(atomic_t *a, int new_value) {
312 if (!a)
313 return 0;
314 int result = (int)(int32_t)atomic_exchange((_Atomic(uint64_t) *)&a->impl, (uint64_t)(int32_t)new_value);
316 return result;
317}
318
320 if (!a)
321 return 0;
322 uint64_t result = atomic_exchange((_Atomic(uint64_t) *)&a->impl, new_value);
324 return result;
325}
326
327// ============================================================================
328// Debug Hooks (called from wrapper functions in debug builds)
329// ============================================================================
330
331// Forward declare the initialization state from lib/debug/atomic.c
332extern bool debug_atomic_is_initialized(void);
333
335 if (!a || !debug_atomic_is_initialized())
336 return;
338 a->load_count++;
339}
340
342 if (!a || !debug_atomic_is_initialized())
343 return;
345 a->store_count++;
346}
347
348void atomic_on_cas(atomic_t *a, bool success) {
349 if (!a || !debug_atomic_is_initialized())
350 return;
351 a->cas_count++;
352 if (success) {
355 }
356}
357
359 if (!a || !debug_atomic_is_initialized())
360 return;
361 a->fetch_count++;
363}
364
366 if (!a || !debug_atomic_is_initialized())
367 return;
369 a->load_count++;
370}
371
373 if (!a || !debug_atomic_is_initialized())
374 return;
376 a->store_count++;
377}
378
379void atomic_ptr_on_cas(atomic_ptr_t *a, bool success) {
380 if (!a || !debug_atomic_is_initialized())
381 return;
382 a->cas_count++;
383 if (success) {
386 }
387}
388
390 if (!a || !debug_atomic_is_initialized())
391 return;
392 a->exchange_count++;
394}
395
396#endif // !NDEBUG
uint64_t atomic_fetch_add_u64(atomic_t *a, uint64_t delta)
Atomically add to a uint64_t and return the previous value.
Definition atomic.c:248
void atomic_ptr_on_load(atomic_ptr_t *a)
Definition atomic.c:365
bool atomic_cas_int_impl(atomic_t *a, int *expected, int new_value)
Definition atomic.c:107
bool atomic_cas_u64(atomic_t *a, uint64_t *expected, uint64_t new_value)
Atomically compare-and-swap a uint64_t.
Definition atomic.c:264
void * atomic_ptr_exchange(atomic_ptr_t *a, void *new_value)
Atomically exchange a pointer and return the old value.
Definition atomic.c:295
void atomic_ptr_store_impl(atomic_ptr_t *a, void *value)
Definition atomic.c:127
int atomic_fetch_add_int_impl(atomic_t *a, int64_t delta)
Definition atomic.c:61
void atomic_on_cas(atomic_t *a, bool success)
Definition atomic.c:348
uint64_t atomic_exchange_u64_impl(atomic_t *a, uint64_t new_value)
Definition atomic.c:157
void atomic_store_bool(atomic_t *a, bool value)
Atomically store a boolean value.
Definition atomic.c:177
void atomic_ptr_store(atomic_ptr_t *a, void *value)
Atomically store a pointer.
Definition atomic.c:280
int atomic_fetch_add_int(atomic_t *a, int delta)
Atomically add to an int and return the previous value.
Definition atomic.c:209
bool atomic_load_bool(atomic_t *a)
Atomically load a boolean value.
Definition atomic.c:169
void atomic_ptr_on_cas(atomic_ptr_t *a, bool success)
Definition atomic.c:379
void * atomic_ptr_load(atomic_ptr_t *a)
Atomically load a pointer.
Definition atomic.c:272
uint64_t atomic_exchange_u64(atomic_t *a, uint64_t new_value)
Atomically exchange a uint64_t and return the old value.
Definition atomic.c:319
int atomic_fetch_sub_int(atomic_t *a, int delta)
Atomically subtract from an int and return the previous value.
Definition atomic.c:217
bool atomic_cas_bool_impl(atomic_t *a, bool *expected, bool new_value)
Definition atomic.c:36
int atomic_load_int_impl(const atomic_t *a)
Definition atomic.c:49
bool atomic_cas_u64_impl(atomic_t *a, uint64_t *expected, uint64_t new_value)
Definition atomic.c:101
void atomic_ptr_on_store(atomic_ptr_t *a)
Definition atomic.c:372
void atomic_store_u64_impl(atomic_t *a, uint64_t value)
Definition atomic.c:83
void atomic_on_load(atomic_t *a)
Definition atomic.c:334
uint64_t atomic_load_u64_impl(const atomic_t *a)
Definition atomic.c:77
void * atomic_ptr_exchange_impl(atomic_ptr_t *a, void *new_value)
Definition atomic.c:139
uint64_t atomic_fetch_add_u64_impl(atomic_t *a, uint64_t delta)
Definition atomic.c:89
int atomic_fetch_sub_int_impl(atomic_t *a, int64_t delta)
Definition atomic.c:67
bool atomic_ptr_cas_impl(atomic_ptr_t *a, void **expected, void *new_value)
Definition atomic.c:133
bool atomic_load_bool_impl(const atomic_t *a)
Definition atomic.c:24
uint64_t atomic_fetch_sub_u64(atomic_t *a, uint64_t delta)
Atomically subtract from a uint64_t and return the previous value.
Definition atomic.c:256
void atomic_store_u64(atomic_t *a, uint64_t value)
Atomically store a uint64_t value.
Definition atomic.c:241
void atomic_store_int(atomic_t *a, int value)
Atomically store an int value.
Definition atomic.c:202
void atomic_store_bool_impl(atomic_t *a, uint64_t value)
Definition atomic.c:30
bool atomic_cas_int(atomic_t *a, int *expected, int new_value)
Atomically compare-and-swap an int.
Definition atomic.c:225
void atomic_ptr_on_exchange(atomic_ptr_t *a)
Definition atomic.c:389
void atomic_store_int_impl(atomic_t *a, uint64_t value)
Definition atomic.c:55
void atomic_on_fetch(atomic_t *a)
Definition atomic.c:358
bool debug_atomic_is_initialized(void)
int atomic_exchange_int_impl(atomic_t *a, int new_value)
Definition atomic.c:151
int atomic_exchange_int(atomic_t *a, int new_value)
Atomically exchange an int and return the old value.
Definition atomic.c:311
void * atomic_ptr_load_impl(const atomic_ptr_t *a)
Definition atomic.c:121
uint64_t atomic_fetch_sub_u64_impl(atomic_t *a, uint64_t delta)
Definition atomic.c:95
uint64_t atomic_load_u64(atomic_t *a)
Atomically load a uint64_t value.
Definition atomic.c:233
void atomic_on_store(atomic_t *a)
Definition atomic.c:341
bool atomic_exchange_bool_impl(atomic_t *a, bool new_value)
Definition atomic.c:145
bool atomic_exchange_bool(atomic_t *a, bool new_value)
Atomically exchange a boolean and return the old value.
Definition atomic.c:303
int atomic_load_int(atomic_t *a)
Atomically load an int value.
Definition atomic.c:194
bool atomic_ptr_cas(atomic_ptr_t *a, void **expected, void *new_value)
Atomically compare-and-swap a pointer.
Definition atomic.c:287
bool atomic_cas_bool(atomic_t *a, bool *expected, bool new_value)
Atomically compare-and-swap a boolean.
Definition atomic.c:184
⚛️ Atomic operations abstraction layer with debug tracking
unsigned long long uint64_t
Definition common.h:59
uint64_t time_get_ns(void)
Get current monotonic time in nanoseconds.
Definition util/time.c:108
#define bool
Definition stdbool.h:61
Atomic pointer wrapper.
Definition atomic.h:106
uint64_t last_load_time_ns
Definition atomic.h:110
uint64_t store_count
Definition atomic.h:111
uint64_t cas_success_count
Definition atomic.h:114
uint64_t cas_count
Definition atomic.h:113
uint64_t last_store_time_ns
Definition atomic.h:109
uint64_t exchange_count
Definition atomic.h:115
uint64_t load_count
Definition atomic.h:112
Atomic value wrapper for integral/boolean types.
Definition atomic.h:76
uint64_t last_load_time_ns
Definition atomic.h:80
uint64_t fetch_count
Definition atomic.h:85
uint64_t cas_count
Definition atomic.h:83
uint64_t store_count
Definition atomic.h:81
uint64_t load_count
Definition atomic.h:82
uint64_t last_store_time_ns
Definition atomic.h:79
uint64_t cas_success_count
Definition atomic.h:84
⏱️ High-precision timing utilities using sokol_time.h and uthash