le_atomic.h

1 /**
2  * @page c_atomic Atomic Operation API
3  *
4  * @subpage le_atomic.ch "API Reference"
5  *
6  * <HR>
7  *
8  * An atomic operation interface for Legato. Using an atomic operation has two effects:
9  * - Ensures all threads either see the whole operation performed, or none of it, and
10  * - Provides guarantees on when the effects of an operation are seen by other threads,
11  * relative to the surrounding code.
12  */
13 
14 #ifndef LEGATO_ATOMIC_INCLUDE_GUARD
15 #define LEGATO_ATOMIC_INCLUDE_GUARD
16 
17 #ifdef __GNUC__
18 
19 /**
20  * Does not create ordering constraints between threads.
21  */
22 #define LE_ATOMIC_ORDER_RELAXED __ATOMIC_RELAXED
23 
24 /**
25  * Creates a constraint that guarantees this operation will occur before all later operations,
26  * as seen by all threads.
27  */
28 #define LE_ATOMIC_ORDER_ACQUIRE __ATOMIC_ACQUIRE
29 
30 /**
31  * Creates a constraint that guarantees this operation will occur after all previous operations,
32  * as seen by all threads.
33  */
34 #define LE_ATOMIC_ORDER_RELEASE __ATOMIC_RELEASE
35 
36 /**
37  * Combines the effects of LE_ATOMIC_ORDER_ACQUIRE and LE_ATOMIC_ORDER_RELEASE
38  */
39 #define LE_ATOMIC_ORDER_ACQ_REL __ATOMIC_ACQ_REL
40 
41 /**
42  * Test if a value has previously been set, and set it to true. This returns true if and only if
43  * the value was previously true.
44  *
45  * @param ptr points to a bool.
46  * @param order ordering constraint
47  */
48 #define LE_ATOMIC_TEST_AND_SET(ptr, order) __atomic_test_and_set((ptr), (order))
49 
50 /**
51  * Performs an atomic add operation. Results are stored in address pointed to by ptr
52  *
53  * @return output value of operation
54  */
55 #define LE_ATOMIC_ADD_FETCH(ptr, value, order) __sync_add_and_fetch((ptr), (value))
56 
57 /**
58  * Performs an atomic subtract operation. Results are stored in address pointed to by ptr
59  *
60  * @return output value of operation
61  */
62 #define LE_ATOMIC_SUB_FETCH(ptr, value, order) __sync_sub_and_fetch((ptr), (value))
63 
64 /**
65  * Performs an atomic bitwise-OR operation. Results are stored in address pointed to by ptr
66  *
67  * @return output value of operation
68  */
69 #define LE_ATOMIC_OR_FETCH(ptr, value, order) __sync_or_and_fetch((ptr), (value))
70 
71 /**
72  * Performs an atomic bitwise-AND operation. Results are stored in address pointed to by ptr
73  *
74  * @return output value of operation
75  */
76 #define LE_ATOMIC_AND_FETCH(ptr, value, order) __sync_and_and_fetch((ptr), (value))
77 
78 /**
79  * Perform an atomic compare and swap. If the current value of *ptr is oldval, then write newval
80  * into *ptr.
81  *
82  * @return True if comparison is successful and newval was written
83  */
84 #define LE_SYNC_BOOL_COMPARE_AND_SWAP(ptr, oldval, newval) \
85  __sync_bool_compare_and_swap((ptr), (oldval), (newval))
86 
87 #else /* !__GCC__ */
88 
89 // On compilers other than GCC, the framework adaptor must provide an implementation.
90 #ifndef LE_ATOMIC_ORDER_RELAXED
91 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_ORDER_RELAXED"
92 #endif
93 
94 #ifndef LE_ATOMIC_ORDER_ACQUIRE
95 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_ORDER_ACQUIRE"
96 #endif
97 
98 #ifndef LE_ATOMIC_ORDER_RELEASE
99 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_ORDER_RELEASE"
100 #endif
101 
102 #ifndef LE_ATOMIC_ORDER_ACQ_REL
103 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_ORDER_ACQ_REL"
104 #endif
105 
106 #ifndef LE_ATOMIC_TEST_AND_SET
107 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_TEST_AND_SET"
108 #endif
109 
110 #ifndef LE_ATOMIC_ADD_FETCH
111 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_ADD_FETCH"
112 #endif
113 
114 #ifndef LE_ATOMIC_SUB_FETCH
115 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_SUB_FETCH"
116 #endif
117 
118 #ifndef LE_ATOMIC_OR_FETCH
119 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_OR_FETCH"
120 #endif
121 
122 #ifndef LE_ATOMIC_AND_FETCH
123 #error "The frameworkAdaptor is missing a definition of LE_ATOMIC_AND_FETCH"
124 #endif
125 
126 #ifndef LE_SYNC_BOOL_COMPARE_AND_SWAP
127 #error "The frameworkAdaptor is missing a definition of LE_SYNC_BOOL_COMPARE_AND_SWAP"
128 #endif
129 
130 #endif /* __GCC__ */
131 
132 #endif // LEGATO_ATOMIC_INCLUDE_GUARD