CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
stdatomic.h
Go to the documentation of this file.
1#pragma once
2/**
3 * \file
4 * This file implements the C11 and C++23 C atomics interfaces. On targets
5 * without hardware atomics, these will all lower to calls into the atomics
6 * shared library. You must link either atomics or atomics_fixed (if you use
7 * only fixed-width atomics) into your firmware image.
8 *
9 * *WARNING*: The C++ atomics interface is more efficient for non-primitive
10 * types but is *not* guaranteed to be interoperable with the C version.
11 * Interoperable code should use only primitive types in atomics.
12 */
13
14#ifdef __cplusplus
15# include <atomic>
16# define _Atomic(T) std::atomic<T>
17#else
18# include <cdefs.h>
19# include <stddef.h>
20# include <stdint.h>
21enum memory_order
22{
23 memory_order_relaxed = __ATOMIC_RELAXED,
24 memory_order_consume = __ATOMIC_CONSUME,
25 memory_order_acquire = __ATOMIC_ACQUIRE,
26 memory_order_release = __ATOMIC_RELEASE,
27 memory_order_acq_rel = __ATOMIC_ACQ_REL,
28 memory_order_seq_cst = __ATOMIC_SEQ_CST,
29};
30
31typedef _Atomic(_Bool) atomic_flag;
32
33# define ATOMIC_FLAG_INIT false
34
35// Clang thinks that all atomics are too big, so ignore it.
36__clang_ignored_warning_push("-Watomic-alignment")
37
38 __always_inline static inline _Bool
39 atomic_flag_test_and_set_explicit(volatile atomic_flag *obj,
40 enum memory_order order)
41{
42 return __c11_atomic_exchange(obj, 1, order);
43}
44
45__always_inline static inline _Bool
46atomic_flag_test_and_set(volatile atomic_flag *obj)
47{
48 return atomic_flag_test_and_set_explicit(obj, memory_order_seq_cst);
49}
50
51__always_inline static inline _Bool
52atomic_flag_test_and_clear_explicit(volatile atomic_flag *obj,
53 enum memory_order order)
54{
55 return __c11_atomic_exchange(obj, 0, order);
56}
57
58__always_inline static inline _Bool
59atomic_flag_test_and_clear(volatile atomic_flag *obj)
60{
61 return atomic_flag_test_and_clear_explicit(obj, memory_order_seq_cst);
62}
63
64__clang_ignored_warning_pop()
65
66// The functions in the following block are mapped directly to builtins.
67# define atomic_init(obj, value) __c11_atomic_init(obj, value)
68# define atomic_compare_exchange_strong_explicit( \
69 object, expected, desired, success, failure) \
70 __c11_atomic_compare_exchange_strong( \
71 object, expected, desired, success, failure)
72# define atomic_compare_exchange_weak_explicit( \
73 object, expected, desired, success, failure) \
74 __c11_atomic_compare_exchange_weak( \
75 object, expected, desired, success, failure)
76# define atomic_exchange_explicit(object, desired, order) \
77 __c11_atomic_exchange(object, desired, order)
78# define atomic_fetch_add_explicit(object, operand, order) \
79 __c11_atomic_fetch_add(object, operand, order)
80# define atomic_fetch_and_explicit(object, operand, order) \
81 __c11_atomic_fetch_and(object, operand, order)
82# define atomic_fetch_or_explicit(object, operand, order) \
83 __c11_atomic_fetch_or(object, operand, order)
84# define atomic_fetch_sub_explicit(object, operand, order) \
85 __c11_atomic_fetch_sub(object, operand, order)
86# define atomic_fetch_xor_explicit(object, operand, order) \
87 __c11_atomic_fetch_xor(object, operand, order)
88# define atomic_load_explicit(object, order) __c11_atomic_load(object, order)
89# define atomic_store_explicit(object, desired, order) \
90 __c11_atomic_store(object, desired, order)
91
92// The functions in the following block are convenience wrappers around the
93// previous block
94
95# define atomic_compare_exchange_strong(object, expected, desired) \
96 atomic_compare_exchange_strong_explicit(object, \
97 expected, \
98 desired, \
99 memory_order_seq_cst, \
100 memory_order_seq_cst)
101# define atomic_compare_exchange_weak(object, expected, desired) \
102 atomic_compare_exchange_weak_explicit(object, \
103 expected, \
104 desired, \
105 memory_order_seq_cst, \
106 memory_order_seq_cst)
107# define atomic_exchange(object, desired) \
108 atomic_exchange_explicit(object, desired, memory_order_seq_cst)
109# define atomic_fetch_add(object, operand) \
110 atomic_fetch_add_explicit(object, operand, memory_order_seq_cst)
111# define atomic_fetch_and(object, operand) \
112 atomic_fetch_and_explicit(object, operand, memory_order_seq_cst)
113# define atomic_fetch_or(object, operand) \
114 atomic_fetch_or_explicit(object, operand, memory_order_seq_cst)
115# define atomic_fetch_sub(object, operand) \
116 atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst)
117# define atomic_fetch_xor(object, operand) \
118 atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst)
119# define atomic_load(object) \
120 atomic_load_explicit(object, memory_order_seq_cst)
121# define atomic_store(object, desired) \
122 atomic_store_explicit(object, desired, memory_order_seq_cst)
123#endif
124
125typedef _Atomic(_Bool) atomic_bool;
126typedef _Atomic(char) atomic_char;
127typedef _Atomic(signed char) atomic_schar;
128typedef _Atomic(unsigned char) atomic_uchar;
129typedef _Atomic(short) atomic_short;
130typedef _Atomic(unsigned short) atomic_ushort;
131typedef _Atomic(int) atomic_int;
132typedef _Atomic(unsigned int) atomic_uint;
133typedef _Atomic(long) atomic_long;
134typedef _Atomic(unsigned long) atomic_ulong;
135typedef _Atomic(long long) atomic_llong;
136typedef _Atomic(unsigned long long) atomic_ullong;
137typedef _Atomic(int_least8_t) atomic_int_least8_t;
138typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
139typedef _Atomic(int_least16_t) atomic_int_least16_t;
140typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
141typedef _Atomic(int_least32_t) atomic_int_least32_t;
142typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
143typedef _Atomic(int_least64_t) atomic_int_least64_t;
144typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
145typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
146typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
147typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
148typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
149typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
150typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
151typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
152typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
153typedef _Atomic(intptr_t) atomic_intptr_t;
154typedef _Atomic(uintptr_t) atomic_uintptr_t;
155typedef _Atomic(size_t) atomic_size_t;
156typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;