ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
atomic.h
Go to the documentation of this file.
1
38#pragma once
39
40#include <stdatomic.h>
41#include <stdbool.h>
42#include <stdint.h>
43#include <stddef.h>
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49// ============================================================================
50// Core Atomic Types
51// ============================================================================
52
88
118
119
120// ============================================================================
121// bool Operations
122// ============================================================================
123
129#ifndef NDEBUG
131#else
132#define atomic_load_bool(a) ((bool)atomic_load_bool_impl(a))
133#endif
134
135bool atomic_load_bool_impl(const atomic_t *a);
136
142#ifndef NDEBUG
143void atomic_store_bool(atomic_t *a, bool value);
144#else
145#define atomic_store_bool(a, value) atomic_store_bool_impl((a), (uint64_t)(value))
146#endif
147
149
157#ifndef NDEBUG
158bool atomic_cas_bool(atomic_t *a, bool *expected, bool new_value);
159#else
160#define atomic_cas_bool(a, expected, new_value) \
161 atomic_cas_bool_impl((a), (expected), (new_value))
162#endif
163
164bool atomic_cas_bool_impl(atomic_t *a, bool *expected, bool new_value);
165
175#ifndef NDEBUG
176bool atomic_exchange_bool(atomic_t *a, bool new_value);
177#else
178#define atomic_exchange_bool(a, new_value) \
179 atomic_exchange_bool_impl((a), (new_value))
180#endif
181
182bool atomic_exchange_bool_impl(atomic_t *a, bool new_value);
183
184// ============================================================================
185// int Operations
186// ============================================================================
187
193#ifndef NDEBUG
195#else
196#define atomic_load_int(a) ((int)atomic_load_int_impl(a))
197#endif
198
199int atomic_load_int_impl(const atomic_t *a);
200
206#ifndef NDEBUG
207void atomic_store_int(atomic_t *a, int value);
208#else
209#define atomic_store_int(a, value) atomic_store_int_impl((a), (uint64_t)(int32_t)(value))
210#endif
211
213
220#ifndef NDEBUG
221int atomic_fetch_add_int(atomic_t *a, int delta);
222#else
223#define atomic_fetch_add_int(a, delta) \
224 ((int)atomic_fetch_add_int_impl((a), (int64_t)(delta)))
225#endif
226
227int atomic_fetch_add_int_impl(atomic_t *a, int64_t delta);
228
235#ifndef NDEBUG
236int atomic_fetch_sub_int(atomic_t *a, int delta);
237#else
238#define atomic_fetch_sub_int(a, delta) \
239 ((int)atomic_fetch_sub_int_impl((a), (int64_t)(delta)))
240#endif
241
242int atomic_fetch_sub_int_impl(atomic_t *a, int64_t delta);
243
251#ifndef NDEBUG
252bool atomic_cas_int(atomic_t *a, int *expected, int new_value);
253#else
254#define atomic_cas_int(a, expected, new_value) \
255 atomic_cas_int_impl((a), (expected), (new_value))
256#endif
257
258bool atomic_cas_int_impl(atomic_t *a, int *expected, int new_value);
259
260// ============================================================================
261// uint64_t Operations
262// ============================================================================
263
269#ifndef NDEBUG
271#else
272#define atomic_load_u64(a) atomic_load_u64_impl(a)
273#endif
274
276
282#ifndef NDEBUG
283void atomic_store_u64(atomic_t *a, uint64_t value);
284#else
285#define atomic_store_u64(a, value) atomic_store_u64_impl((a), (value))
286#endif
287
289
296#ifndef NDEBUG
298#else
299#define atomic_fetch_add_u64(a, delta) atomic_fetch_add_u64_impl((a), (delta))
300#endif
301
303
310#ifndef NDEBUG
312#else
313#define atomic_fetch_sub_u64(a, delta) atomic_fetch_sub_u64_impl((a), (delta))
314#endif
315
317
325#ifndef NDEBUG
326bool atomic_cas_u64(atomic_t *a, uint64_t *expected, uint64_t new_value);
327#else
328#define atomic_cas_u64(a, expected, new_value) \
329 atomic_cas_u64_impl((a), (expected), (new_value))
330#endif
331
332bool atomic_cas_u64_impl(atomic_t *a, uint64_t *expected, uint64_t new_value);
333
349#ifndef NDEBUG
351#else
352#define atomic_exchange_u64(a, new_value) \
353 atomic_exchange_u64_impl((a), (new_value))
354#endif
355
357
358// ============================================================================
359// Pointer Operations
360// ============================================================================
361
367#ifndef NDEBUG
369#else
370#define atomic_ptr_load(a) atomic_ptr_load_impl(a)
371#endif
372
373void *atomic_ptr_load_impl(const atomic_ptr_t *a);
374
380#ifndef NDEBUG
381void atomic_ptr_store(atomic_ptr_t *a, void *value);
382#else
383#define atomic_ptr_store(a, value) atomic_ptr_store_impl((a), (value))
384#endif
385
386void atomic_ptr_store_impl(atomic_ptr_t *a, void *value);
387
395#ifndef NDEBUG
396bool atomic_ptr_cas(atomic_ptr_t *a, void **expected, void *new_value);
397#else
398#define atomic_ptr_cas(a, expected, new_value) \
399 atomic_ptr_cas_impl((a), (expected), (new_value))
400#endif
401
402bool atomic_ptr_cas_impl(atomic_ptr_t *a, void **expected, void *new_value);
403
410#ifndef NDEBUG
411void *atomic_ptr_exchange(atomic_ptr_t *a, void *new_value);
412#else
413#define atomic_ptr_exchange(a, new_value) \
414 atomic_ptr_exchange_impl((a), (new_value))
415#endif
416
417void *atomic_ptr_exchange_impl(atomic_ptr_t *a, void *new_value);
418
425#ifndef NDEBUG
426int atomic_exchange_int(atomic_t *a, int new_value);
427#else
428#define atomic_exchange_int(a, new_value) \
429 atomic_exchange_int_impl((a), (new_value))
430#endif
431
432int atomic_exchange_int_impl(atomic_t *a, int new_value);
433
434// ============================================================================
435// Debug Hooks (called by _impl functions in debug builds)
436// ============================================================================
437
438#ifndef NDEBUG
439void atomic_on_load(atomic_t *a);
441void atomic_on_cas(atomic_t *a, bool success);
443
446void atomic_ptr_on_cas(atomic_ptr_t *a, bool success);
448#endif
449
450// ============================================================================
451// Convenience Macros for Atomic Declaration and Registration
452// ============================================================================
453
472#define ATOMIC_REGISTER_AUTO(name, parent_ptr) NAMED_REGISTER_ATOMIC(&(name), #name, (uintptr_t)(const void *)(parent_ptr))
473
485#define ATOMIC_PTR_REGISTER_AUTO(name) NAMED_REGISTER_ATOMIC_PTR(&(name), #name)
486
487// ============================================================================
488// Automatic Named Initialization & Registration Macros
489// ============================================================================
490
509#ifndef NDEBUG
510#define ATOMIC_INIT_AUTO(...) = _atomic_init_auto(__VA_ARGS__)
511#else
512#define ATOMIC_INIT_AUTO(...) = {0}
513#endif
514
520#ifndef NDEBUG
521#define ATOMIC_PTR_INIT_AUTO(...) = _atomic_ptr_init_auto(__VA_ARGS__)
522#else
523#define ATOMIC_PTR_INIT_AUTO(...) = {0}
524#endif
525
526// Actual init functions (defined below - use a workaround pattern)
527// These are helpers that work with static initialization
528#define _atomic_init_auto(name) {0}; \
529 static void __attribute__((constructor, used)) _atomic_reg_##name(void) { \
530 NAMED_REGISTER_ATOMIC(&name, #name, NULL); \
531 } typedef int _atomic_assert_##name
532
533#define _atomic_ptr_init_auto(name) {0}; \
534 static void __attribute__((constructor, used)) _atomic_ptr_reg_##name(void) { \
535 NAMED_REGISTER_ATOMIC_PTR(&name, #name, NULL); \
536 } typedef int _atomic_ptr_assert_##name
537
538// ============================================================================
539// Debug Initialization/Shutdown
540// ============================================================================
541
542#ifndef NDEBUG
543void debug_atomic_init(void);
544void debug_atomic_shutdown(void);
546void debug_atomic_print_state(void);
547#else
548#define debug_atomic_init() ((void)0)
549#define debug_atomic_shutdown() ((void)0)
550#define debug_atomic_is_initialized() (true)
551#define debug_atomic_print_state() ((void)0)
552#endif
553
554#ifdef __cplusplus
555}
556#endif
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
void debug_atomic_init(void)
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 debug_atomic_print_state(void)
void debug_atomic_shutdown(void)
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
unsigned long long uint64_t
Definition common.h:59
ClangTool/LibTooling compatibility shim for stdbool.h.
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
_Atomic(void *) impl
Underlying C11 atomic pointer.
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
_Atomic(uint64_t) impl
Underlying C11 atomic value.
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