[2f0a0936] | 1 | /** |
---|
| 2 | * @file rtems/score/atomic.h |
---|
| 3 | * |
---|
| 4 | * This include file defines the interface for all the atomic |
---|
| 5 | * operations which can be used in the synchronization primitives |
---|
| 6 | * or in the lock-less algorithms. You should not use these API |
---|
| 7 | * in the other components directly. |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | /* |
---|
[1180099] | 11 | * COPYRIGHT (c) 2012-2013 Deng Hengyi. |
---|
[2f0a0936] | 12 | * |
---|
| 13 | * The license and distribution terms for this file may be |
---|
| 14 | * found in the file LICENSE in this distribution or at |
---|
| 15 | * http://www.rtems.com/license/LICENSE. |
---|
| 16 | */ |
---|
| 17 | |
---|
| 18 | #ifndef _RTEMS_SCORE_ATOMIC_H |
---|
| 19 | #define _RTEMS_SCORE_ATOMIC_H |
---|
| 20 | |
---|
| 21 | #include <rtems/score/cpuatomic.h> |
---|
| 22 | |
---|
| 23 | #ifdef __cplusplus |
---|
| 24 | extern "C" { |
---|
| 25 | #endif |
---|
| 26 | |
---|
| 27 | /** |
---|
| 28 | * @defgroup RTEMS atomic interface |
---|
| 29 | * |
---|
| 30 | */ |
---|
| 31 | |
---|
| 32 | /**@{*/ |
---|
| 33 | |
---|
[697d31e] | 34 | /** |
---|
| 35 | * @brief atomic data initializer for static initialization. |
---|
| 36 | */ |
---|
[29f7d317] | 37 | #define ATOMIC_INITIALIZER_ULONG(value) CPU_ATOMIC_INITIALIZER_ULONG(value) |
---|
[697d31e] | 38 | #define ATOMIC_INITIALIZER_PTR(value) CPU_ATOMIC_INITIALIZER_PTR(value) |
---|
[03aad60] | 39 | |
---|
| 40 | /** |
---|
| 41 | * @brief Initializes an atomic flag object to the cleared state. |
---|
| 42 | */ |
---|
| 43 | #define ATOMIC_INITIALIZER_FLAG CPU_ATOMIC_INITIALIZER_FLAG |
---|
[697d31e] | 44 | |
---|
| 45 | /** |
---|
| 46 | * @brief Initializes an atomic type value into a atomic object. |
---|
| 47 | * |
---|
| 48 | * @param object an atomic type pointer of object. |
---|
[3bac8a4c] | 49 | * @param pointer a pointer to be stored into object. |
---|
[697d31e] | 50 | */ |
---|
[29f7d317] | 51 | static inline void _Atomic_Init_ulong( |
---|
| 52 | volatile Atomic_Ulong *object, |
---|
| 53 | unsigned long value |
---|
[697d31e] | 54 | ) |
---|
| 55 | { |
---|
[29f7d317] | 56 | _CPU_atomic_Init_ulong(object, value); |
---|
[697d31e] | 57 | } |
---|
| 58 | |
---|
[4288f9fd] | 59 | static inline void _Atomic_Init_ptr( |
---|
[697d31e] | 60 | volatile Atomic_Pointer *object, |
---|
[3bac8a4c] | 61 | void *pointer |
---|
[697d31e] | 62 | ) |
---|
| 63 | { |
---|
[3bac8a4c] | 64 | _CPU_atomic_Init_ptr(object, pointer); |
---|
[697d31e] | 65 | } |
---|
| 66 | |
---|
[2f0a0936] | 67 | /** |
---|
[1180099] | 68 | * @brief Atomically load an atomic type value from atomic object. |
---|
| 69 | * |
---|
| 70 | * @param object an atomic type pointer of object. |
---|
| 71 | * @param order a type of Atomic_Order. |
---|
| 72 | * |
---|
| 73 | * The order shall not be ATOMIC_ORDER_RELEASE. |
---|
[2f0a0936] | 74 | */ |
---|
[29f7d317] | 75 | static inline unsigned long _Atomic_Load_ulong( |
---|
| 76 | volatile Atomic_Ulong *object, |
---|
[1180099] | 77 | Atomic_Order order |
---|
| 78 | ) |
---|
| 79 | { |
---|
[29f7d317] | 80 | return _CPU_atomic_Load_ulong( object, order ); |
---|
[1180099] | 81 | } |
---|
| 82 | |
---|
[3bac8a4c] | 83 | static inline void *_Atomic_Load_ptr( |
---|
[1180099] | 84 | volatile Atomic_Pointer *object, |
---|
| 85 | Atomic_Order order |
---|
| 86 | ) |
---|
| 87 | { |
---|
| 88 | return _CPU_atomic_Load_ptr( object, order ); |
---|
| 89 | } |
---|
[2f0a0936] | 90 | |
---|
| 91 | /** |
---|
[1180099] | 92 | * @brief Atomically store an atomic type value into a atomic object. |
---|
| 93 | * |
---|
| 94 | * @param object an atomic type pointer of object. |
---|
| 95 | * @param value a value to be stored into object. |
---|
| 96 | * @param order a type of Atomic_Order. |
---|
| 97 | * |
---|
| 98 | * The order shall not be ATOMIC_ORDER_ACQUIRE. |
---|
[2f0a0936] | 99 | */ |
---|
[29f7d317] | 100 | static inline void _Atomic_Store_ulong( |
---|
| 101 | volatile Atomic_Ulong *object, |
---|
| 102 | unsigned long value, |
---|
[1180099] | 103 | Atomic_Order order |
---|
| 104 | ) |
---|
| 105 | { |
---|
[29f7d317] | 106 | _CPU_atomic_Store_ulong( object, value, order ); |
---|
[1180099] | 107 | } |
---|
| 108 | |
---|
[4288f9fd] | 109 | static inline void _Atomic_Store_ptr( |
---|
[1180099] | 110 | volatile Atomic_Pointer *object, |
---|
[3bac8a4c] | 111 | void *pointer, |
---|
[1180099] | 112 | Atomic_Order order |
---|
| 113 | ) |
---|
| 114 | { |
---|
[3bac8a4c] | 115 | _CPU_atomic_Store_ptr( object, pointer, order ); |
---|
[1180099] | 116 | } |
---|
[2f0a0936] | 117 | |
---|
| 118 | /** |
---|
[1180099] | 119 | * @brief Atomically load-add-store an atomic type value into object |
---|
| 120 | * |
---|
| 121 | * @param object a atomic type pointer of object. |
---|
| 122 | * @param value a value to be add and store into object. |
---|
| 123 | * @param order a type of Atomic_Order. |
---|
| 124 | * |
---|
[3d68be1] | 125 | * @retval a result value before add ops. |
---|
[2f0a0936] | 126 | */ |
---|
[29f7d317] | 127 | static inline unsigned long _Atomic_Fetch_add_ulong( |
---|
| 128 | volatile Atomic_Ulong *object, |
---|
| 129 | unsigned long value, |
---|
[1180099] | 130 | Atomic_Order order |
---|
| 131 | ) |
---|
| 132 | { |
---|
[29f7d317] | 133 | return _CPU_atomic_Fetch_add_ulong( object, value, order ); |
---|
[1180099] | 134 | } |
---|
| 135 | |
---|
[4288f9fd] | 136 | static inline uintptr_t _Atomic_Fetch_add_ptr( |
---|
[1180099] | 137 | volatile Atomic_Pointer *object, |
---|
| 138 | uintptr_t value, |
---|
| 139 | Atomic_Order order |
---|
| 140 | ) |
---|
| 141 | { |
---|
| 142 | return _CPU_atomic_Fetch_add_ptr( object, value, order ); |
---|
| 143 | } |
---|
[2f0a0936] | 144 | |
---|
| 145 | /** |
---|
[1180099] | 146 | * @brief Atomically load-sub-store an atomic type value into object |
---|
| 147 | * |
---|
| 148 | * @param object a atomic type pointer of object. |
---|
| 149 | * @param value a value to be sub and store into object. |
---|
| 150 | * @param order a type of Atomic_Order. |
---|
| 151 | * |
---|
[3d68be1] | 152 | * @retval a result value before sub ops. |
---|
[2f0a0936] | 153 | */ |
---|
[29f7d317] | 154 | static inline unsigned long _Atomic_Fetch_sub_ulong( |
---|
| 155 | volatile Atomic_Ulong *object, |
---|
| 156 | unsigned long value, |
---|
[1180099] | 157 | Atomic_Order order |
---|
| 158 | ) |
---|
| 159 | { |
---|
[29f7d317] | 160 | return _CPU_atomic_Fetch_sub_ulong( object, value, order ); |
---|
[1180099] | 161 | } |
---|
| 162 | |
---|
[4288f9fd] | 163 | static inline uintptr_t _Atomic_Fetch_sub_ptr( |
---|
[1180099] | 164 | volatile Atomic_Pointer *object, |
---|
| 165 | uintptr_t value, |
---|
| 166 | Atomic_Order order |
---|
| 167 | ) |
---|
| 168 | { |
---|
| 169 | return _CPU_atomic_Fetch_sub_ptr( object, value, order ); |
---|
| 170 | } |
---|
[2f0a0936] | 171 | |
---|
| 172 | /** |
---|
[1180099] | 173 | * @brief Atomically load-or-store an atomic type value into object |
---|
| 174 | * |
---|
| 175 | * @param object a atomic type pointer of object. |
---|
| 176 | * @param value a value to be or and store into object. |
---|
| 177 | * @param order a type of Atomic_Order. |
---|
| 178 | * |
---|
[3d68be1] | 179 | * @retval a result value before or ops. |
---|
[2f0a0936] | 180 | */ |
---|
[29f7d317] | 181 | static inline unsigned long _Atomic_Fetch_or_ulong( |
---|
| 182 | volatile Atomic_Ulong *object, |
---|
| 183 | unsigned long value, |
---|
[1180099] | 184 | Atomic_Order order |
---|
| 185 | ) |
---|
| 186 | { |
---|
[29f7d317] | 187 | return _CPU_atomic_Fetch_or_ulong( object, value, order ); |
---|
[1180099] | 188 | } |
---|
| 189 | |
---|
[4288f9fd] | 190 | static inline uintptr_t _Atomic_Fetch_or_ptr( |
---|
[1180099] | 191 | volatile Atomic_Pointer *object, |
---|
| 192 | uintptr_t value, |
---|
| 193 | Atomic_Order order |
---|
| 194 | ) |
---|
| 195 | { |
---|
| 196 | return _CPU_atomic_Fetch_or_ptr( object, value, order ); |
---|
| 197 | } |
---|
[2f0a0936] | 198 | |
---|
| 199 | /** |
---|
[1180099] | 200 | * @brief Atomically load-and-store an atomic type value into object |
---|
| 201 | * |
---|
| 202 | * @param object a atomic type pointer of object. |
---|
| 203 | * @param value a value to be and and store into object. |
---|
| 204 | * @param order a type of Atomic_Order. |
---|
| 205 | * |
---|
[3d68be1] | 206 | * @retval a result value before and ops. |
---|
[2f0a0936] | 207 | */ |
---|
[29f7d317] | 208 | static inline unsigned long _Atomic_Fetch_and_ulong( |
---|
| 209 | volatile Atomic_Ulong *object, |
---|
| 210 | unsigned long value, |
---|
[1180099] | 211 | Atomic_Order order |
---|
| 212 | ) |
---|
| 213 | { |
---|
[29f7d317] | 214 | return _CPU_atomic_Fetch_and_ulong( object, value, order ); |
---|
[1180099] | 215 | } |
---|
| 216 | |
---|
[4288f9fd] | 217 | static inline uintptr_t _Atomic_Fetch_and_ptr( |
---|
[1180099] | 218 | volatile Atomic_Pointer *object, |
---|
| 219 | uintptr_t value, |
---|
| 220 | Atomic_Order order |
---|
| 221 | ) |
---|
| 222 | { |
---|
| 223 | return _CPU_atomic_Fetch_and_ptr( object, value, order ); |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | /** |
---|
| 227 | * @brief Atomically exchange an atomic type value into object |
---|
| 228 | * |
---|
| 229 | * @param object a atomic type pointer of object. |
---|
| 230 | * @param value a value to exchange and and store into object. |
---|
| 231 | * @param order a type of Atomic_Order. |
---|
| 232 | * |
---|
[3d68be1] | 233 | * @retval a result value before exchange ops. |
---|
[1180099] | 234 | */ |
---|
[29f7d317] | 235 | static inline unsigned long _Atomic_Exchange_ulong( |
---|
| 236 | volatile Atomic_Ulong *object, |
---|
| 237 | unsigned long value, |
---|
[1180099] | 238 | Atomic_Order order |
---|
| 239 | ) |
---|
| 240 | { |
---|
[29f7d317] | 241 | return _CPU_atomic_Exchange_ulong( object, value, order ); |
---|
[1180099] | 242 | } |
---|
| 243 | |
---|
[3bac8a4c] | 244 | static inline void *_Atomic_Exchange_ptr( |
---|
[1180099] | 245 | volatile Atomic_Pointer *object, |
---|
[3bac8a4c] | 246 | void *pointer, |
---|
[1180099] | 247 | Atomic_Order order |
---|
| 248 | ) |
---|
| 249 | { |
---|
[3bac8a4c] | 250 | return _CPU_atomic_Exchange_ptr( object, pointer, order ); |
---|
[1180099] | 251 | } |
---|
[2f0a0936] | 252 | |
---|
| 253 | /** |
---|
[1180099] | 254 | * @brief Atomically compare the value stored at object with a |
---|
| 255 | * old_value and if the two values are equal, update the value of a |
---|
| 256 | * address with a new_value |
---|
| 257 | * |
---|
| 258 | * @param object a atomic type pointer of object. |
---|
| 259 | * @param old_value pointer of a value. |
---|
| 260 | * @param new_value a atomic type value. |
---|
| 261 | * @param order_succ a type of Atomic_Order for successful exchange. |
---|
| 262 | * @param order_fail a type of Atomic_Order for failed exchange. |
---|
| 263 | * |
---|
| 264 | * @retval true if the compare exchange successully. |
---|
| 265 | * @retval false if the compare exchange failed. |
---|
[2f0a0936] | 266 | */ |
---|
[29f7d317] | 267 | static inline bool _Atomic_Compare_exchange_ulong( |
---|
| 268 | volatile Atomic_Ulong *object, |
---|
| 269 | unsigned long *old_value, |
---|
| 270 | unsigned long new_value, |
---|
[1180099] | 271 | Atomic_Order order_succ, |
---|
| 272 | Atomic_Order order_fail |
---|
| 273 | ) |
---|
| 274 | { |
---|
[29f7d317] | 275 | return _CPU_atomic_Compare_exchange_ulong( object, old_value, new_value, |
---|
[1180099] | 276 | order_succ, order_fail ); |
---|
| 277 | } |
---|
| 278 | |
---|
[4288f9fd] | 279 | static inline bool _Atomic_Compare_exchange_ptr( |
---|
[1180099] | 280 | volatile Atomic_Pointer *object, |
---|
[3bac8a4c] | 281 | void **old_pointer, |
---|
| 282 | void *new_pointer, |
---|
[1180099] | 283 | Atomic_Order order_succ, |
---|
| 284 | Atomic_Order order_fail |
---|
| 285 | ) |
---|
| 286 | { |
---|
[3bac8a4c] | 287 | return _CPU_atomic_Compare_exchange_ptr( object, old_pointer, new_pointer, |
---|
[1180099] | 288 | order_succ, order_fail ); |
---|
| 289 | } |
---|
[2f0a0936] | 290 | |
---|
| 291 | /** |
---|
[03aad60] | 292 | * @brief Atomically clears an atomic flag. |
---|
[1180099] | 293 | * |
---|
[03aad60] | 294 | * @param[in, out] object Pointer to the atomic flag object. |
---|
| 295 | * @param[in] order The atomic memory order. |
---|
[1180099] | 296 | * |
---|
[2f0a0936] | 297 | */ |
---|
[03aad60] | 298 | static inline void _Atomic_Flag_clear( |
---|
| 299 | volatile Atomic_Flag *object, |
---|
| 300 | Atomic_Order order |
---|
[1180099] | 301 | ) |
---|
| 302 | { |
---|
[03aad60] | 303 | _CPU_atomic_Flag_clear( object, order ); |
---|
[1180099] | 304 | } |
---|
[2f0a0936] | 305 | |
---|
[1180099] | 306 | /** |
---|
[03aad60] | 307 | * @brief Atomically tests and sets an atomic flag. |
---|
[1180099] | 308 | * |
---|
[03aad60] | 309 | * @param[in, out] object Pointer to the atomic flag object. |
---|
| 310 | * @param[in] order The atomic memory order. |
---|
[1180099] | 311 | * |
---|
[03aad60] | 312 | * @retval true The atomic flag was already set. |
---|
| 313 | * @retval false Otherwise. |
---|
[1180099] | 314 | */ |
---|
[03aad60] | 315 | static inline bool _Atomic_Flag_test_and_set( |
---|
| 316 | volatile Atomic_Flag *object, |
---|
| 317 | Atomic_Order order |
---|
[1180099] | 318 | ) |
---|
| 319 | { |
---|
[03aad60] | 320 | return _CPU_atomic_Flag_test_and_set( object, order ); |
---|
[1180099] | 321 | } |
---|
[2f0a0936] | 322 | |
---|
| 323 | #ifdef __cplusplus |
---|
| 324 | } |
---|
| 325 | #endif |
---|
| 326 | |
---|
| 327 | /**@}*/ |
---|
| 328 | #endif |
---|
| 329 | /* end of include file */ |
---|