source: rtems/cpukit/score/include/rtems/score/cpustdatomic.h @ 33d0666

4.115
Last change on this file since 33d0666 was 33d0666, checked in by Sebastian Huber <sebastian.huber@…>, on 04/15/14 at 14:20:17

score: Critical fix for SMP

The _Scheduler_SMP_Allocate_processor() and _Thread_Dispatch() exchange
information without locks. Make sure we use the right load/store
ordering.

  • Property mode set to 100644
File size: 10.3 KB
Line 
1/**
2 * @file  rtems/score/cpustdatomic.h
3 *
4 * This include file defines the generic data struct and implementation
5 * based on stdatomic.h for all the support architectures. You should not
6 * include this header file directly, because it will be used by atomic.h
7 * which should be included by score components
8 */
9
10/*
11 * COPYRIGHT (c) 2013 Deng Hengyi.
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.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_
19#define _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_
20
21#include <stdatomic.h>
22#include <stdbool.h>
23#include <stdint.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/**
30 * @defgroup RTEMS general stdatomic data type and implementation.
31 *
32 */
33
34/**@{*/
35
36/**
37 * @brief atomic operation unsigned integer type
38 */
39typedef atomic_uint Atomic_Uint;
40
41/**
42 * @brief atomic operation unsigned long integer type
43 */
44typedef atomic_ulong Atomic_Ulong;
45
46/**
47 * @brief atomic operation unsigned integer the size of a pointer type
48 */
49typedef atomic_uintptr_t Atomic_Pointer;
50
51/**
52 * @brief atomic operation flag type
53 */
54typedef atomic_flag Atomic_Flag;
55
56/**
57 * @brief Memory order according to ISO/IEC 9899:2011.
58 */
59typedef enum {
60  ATOMIC_ORDER_RELAXED = memory_order_relaxed,
61  ATOMIC_ORDER_ACQUIRE = memory_order_acquire,
62  ATOMIC_ORDER_RELEASE = memory_order_release,
63  ATOMIC_ORDER_SEQ_CST = memory_order_seq_cst
64} Atomic_Order;
65
66
67/**
68 * @brief atomic data initializer for static initialization.
69 */
70#define CPU_ATOMIC_INITIALIZER_UINT(value) ATOMIC_VAR_INIT(value)
71#define CPU_ATOMIC_INITIALIZER_ULONG(value) ATOMIC_VAR_INIT(value)
72#define CPU_ATOMIC_INITIALIZER_PTR(pointer) \
73  ATOMIC_VAR_INIT((uintptr_t) pointer)
74
75#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
76
77static inline void _CPU_atomic_Fence(
78  Atomic_Order order
79)
80{
81  atomic_thread_fence( (memory_order) order );
82}
83
84/**
85 * @brief Initializes an atomic type value into a atomic object.
86 *
87 * @param object an atomic type pointer of object.
88 * @param value a value to be stored into object.
89 */
90static inline void _CPU_atomic_Init_uint(
91  volatile Atomic_Uint *object,
92  unsigned int value
93)
94{
95  atomic_init( object, value );
96}
97
98static inline void _CPU_atomic_Init_ulong(
99  volatile Atomic_Ulong *object,
100  unsigned long value
101)
102{
103  atomic_init( object, value );
104}
105
106static inline void _CPU_atomic_Init_ptr(
107  volatile Atomic_Pointer *object,
108  void *pointer
109)
110{
111  atomic_init( object, (uintptr_t) pointer );
112}
113
114/**
115 * @brief Atomically load an atomic type value from atomic object.
116 *
117 * @param object an atomic type pointer of object.
118 * @param order a type of Atomic_Order.
119 *
120 * The order shall not be ATOMIC_ORDER_RELEASE.
121 */
122static inline unsigned int _CPU_atomic_Load_uint(
123  volatile Atomic_Uint *object,
124  Atomic_Order order
125)
126{
127  return atomic_load_explicit( object, (memory_order) order );
128}
129
130static inline unsigned long _CPU_atomic_Load_ulong(
131  volatile Atomic_Ulong *object,
132  Atomic_Order order
133)
134{
135  return atomic_load_explicit( object, (memory_order) order );
136}
137
138static inline void *_CPU_atomic_Load_ptr(
139  volatile Atomic_Pointer *object,
140  Atomic_Order order
141)
142{
143  return (void *) atomic_load_explicit( object, (memory_order) order );
144}
145
146/**
147 * @brief Atomically store an atomic type value into a atomic object.
148 *
149 * @param object an atomic type pointer of object.
150 * @param value a value to be stored into object.
151 * @param order a type of Atomic_Order.
152 *
153 * The order shall not be ATOMIC_ORDER_ACQUIRE.
154 */
155static inline void _CPU_atomic_Store_uint(
156  volatile Atomic_Uint *object,
157  unsigned int value,
158  Atomic_Order order
159)
160{
161  atomic_store_explicit( object, value, (memory_order) order );
162}
163
164static inline void _CPU_atomic_Store_ulong(
165  volatile Atomic_Ulong *object,
166  unsigned long value,
167  Atomic_Order order
168)
169{
170  atomic_store_explicit( object, value, (memory_order) order );
171}
172
173static inline void _CPU_atomic_Store_ptr(
174  volatile Atomic_Pointer *object,
175  void *pointer,
176  Atomic_Order order
177)
178{
179  atomic_store_explicit( object, pointer, (memory_order) order );
180}
181
182/**
183 * @brief Atomically load-add-store an atomic type value into object
184 *
185 * @param object a atomic type pointer of object.
186 * @param value a value to be add and store into object.
187 * @param order a type of Atomic_Order.
188 *
189 * @retval a result value before add ops.
190 */
191static inline unsigned int _CPU_atomic_Fetch_add_uint(
192  volatile Atomic_Uint *object,
193  unsigned int value,
194  Atomic_Order order
195)
196{
197  return atomic_fetch_add_explicit( object, value, (memory_order) order );
198}
199
200static inline unsigned long _CPU_atomic_Fetch_add_ulong(
201  volatile Atomic_Ulong *object,
202  unsigned long value,
203  Atomic_Order order
204)
205{
206  return atomic_fetch_add_explicit( object, value, (memory_order) order );
207}
208
209static inline uintptr_t _CPU_atomic_Fetch_add_ptr(
210  volatile Atomic_Pointer *object,
211  uintptr_t value,
212  Atomic_Order order
213)
214{
215  return atomic_fetch_add_explicit( object, value, (memory_order) order );
216}
217
218/**
219 * @brief Atomically load-sub-store an atomic type value into object
220 *
221 * @param object a atomic type pointer of object.
222 * @param value a value to be sub and store into object.
223 * @param order a type of Atomic_Order.
224 *
225 * @retval a result value before sub ops.
226 */
227static inline unsigned int _CPU_atomic_Fetch_sub_uint(
228  volatile Atomic_Uint *object,
229  unsigned int value,
230  Atomic_Order order
231)
232{
233  return atomic_fetch_sub_explicit( object, value, (memory_order) order );
234}
235
236static inline unsigned long _CPU_atomic_Fetch_sub_ulong(
237  volatile Atomic_Ulong *object,
238  unsigned long value,
239  Atomic_Order order
240)
241{
242  return atomic_fetch_sub_explicit( object, value, (memory_order) order );
243}
244
245static inline uintptr_t _CPU_atomic_Fetch_sub_ptr(
246  volatile Atomic_Pointer *object,
247  uintptr_t value,
248  Atomic_Order order
249)
250{
251  return atomic_fetch_sub_explicit( object, value, (memory_order) order );
252}
253
254/**
255 * @brief Atomically load-or-store an atomic type value into object
256 *
257 * @param object a atomic type pointer of object.
258 * @param value a value to be or and store into object.
259 * @param order a type of Atomic_Order.
260 *
261 * @retval a result value before or ops.
262 */
263static inline unsigned int _CPU_atomic_Fetch_or_uint(
264  volatile Atomic_Uint *object,
265  unsigned int value,
266  Atomic_Order order
267)
268{
269  return atomic_fetch_or_explicit( object, value, (memory_order) order );
270}
271
272static inline unsigned long _CPU_atomic_Fetch_or_ulong(
273  volatile Atomic_Ulong *object,
274  unsigned long value,
275  Atomic_Order order
276)
277{
278  return atomic_fetch_or_explicit( object, value, (memory_order) order );
279}
280
281static inline uintptr_t _CPU_atomic_Fetch_or_ptr(
282  volatile Atomic_Pointer *object,
283  uintptr_t value,
284  Atomic_Order order
285)
286{
287  return atomic_fetch_or_explicit( object, value, (memory_order) order );
288}
289
290/**
291 * @brief Atomically load-and-store an atomic type value into object
292 *
293 * @param object a atomic type pointer of object.
294 * @param value a value to be and and store into object.
295 * @param order a type of Atomic_Order.
296 *
297 * @retval a result value before and ops.
298 */
299static inline unsigned int _CPU_atomic_Fetch_and_uint(
300  volatile Atomic_Uint *object,
301  unsigned int value,
302  Atomic_Order order
303)
304{
305  return atomic_fetch_and_explicit( object, value, (memory_order) order );
306}
307
308static inline unsigned long _CPU_atomic_Fetch_and_ulong(
309  volatile Atomic_Ulong *object,
310  unsigned long value,
311  Atomic_Order order
312)
313{
314  return atomic_fetch_and_explicit( object, value, (memory_order) order );
315}
316
317static inline uintptr_t _CPU_atomic_Fetch_and_ptr(
318  volatile Atomic_Pointer *object,
319  uintptr_t value,
320  Atomic_Order order
321)
322{
323  return atomic_fetch_and_explicit( object, value, (memory_order) order );
324}
325
326/**
327 * @brief Atomically exchange an atomic type value into object
328 *
329 * @param object a atomic type pointer of object.
330 * @param value a value to exchange and and store into object.
331 * @param order a type of Atomic_Order.
332 *
333 * @retval a result value before exchange ops.
334 */
335static inline unsigned int _CPU_atomic_Exchange_uint(
336 volatile Atomic_Uint *object,
337 unsigned int value,
338 Atomic_Order order
339)
340{
341  return atomic_exchange_explicit( object, value, (memory_order) order );
342}
343
344static inline unsigned long _CPU_atomic_Exchange_ulong(
345 volatile Atomic_Ulong *object,
346 unsigned long value,
347 Atomic_Order order
348)
349{
350  return atomic_exchange_explicit( object, value, (memory_order) order );
351}
352
353static inline void *_CPU_atomic_Exchange_ptr(
354 volatile Atomic_Pointer *object,
355 void *pointer,
356 Atomic_Order order
357)
358{
359  return (void *) atomic_exchange_explicit(
360    object,
361    (uintptr_t) pointer,
362    (memory_order) order
363  );
364}
365
366/**
367 * @brief Atomically compare the value stored at object with a
368 * old_value and if the two values are equal, update the value of a
369 * address with a new_value
370 *
371 * @param object a atomic type pointer of object.
372 * @param old_value pointer of a value.
373 * @param new_value a atomic type value.
374 * @param order_succ a type of Atomic_Order for successful exchange.
375 * @param order_fail a type of Atomic_Order for failed exchange.
376 *
377 * @retval true if the compare exchange successully.
378 * @retval false if the compare exchange failed.
379 */
380static inline bool _CPU_atomic_Compare_exchange_uint(
381  volatile Atomic_Uint *object,
382  unsigned int *old_value,
383  unsigned int new_value,
384  Atomic_Order order_succ,
385  Atomic_Order order_fail
386)
387{
388  return atomic_compare_exchange_strong_explicit( object, old_value,
389    new_value, order_succ, order_fail );
390}
391
392static inline bool _CPU_atomic_Compare_exchange_ulong(
393  volatile Atomic_Ulong *object,
394  unsigned long *old_value,
395  unsigned long new_value,
396  Atomic_Order order_succ,
397  Atomic_Order order_fail
398)
399{
400  return atomic_compare_exchange_strong_explicit( object, old_value,
401    new_value, order_succ, order_fail );
402}
403
404static inline bool _CPU_atomic_Compare_exchange_ptr(
405  volatile Atomic_Pointer *object,
406  void **old_pointer,
407  void *new_pointer,
408  Atomic_Order order_succ,
409  Atomic_Order order_fail
410)
411{
412  return atomic_compare_exchange_strong_explicit( object, old_pointer,
413    new_pointer, order_succ, order_fail );
414}
415
416static inline void _CPU_atomic_Flag_clear(
417  volatile Atomic_Flag *object,
418  Atomic_Order order
419)
420{
421  return atomic_flag_clear_explicit( object, (memory_order) order );
422}
423
424static inline bool _CPU_atomic_Flag_test_and_set(
425  volatile Atomic_Flag *object,
426  Atomic_Order order
427)
428{
429  return atomic_flag_test_and_set_explicit( object, (memory_order) order );
430}
431
432#ifdef __cplusplus
433}
434#endif
435
436/**@}*/
437#endif
438/*  end of include file */
Note: See TracBrowser for help on using the repository browser.