source: rtems/cpukit/include/rtems/score/cpustdatomic.h @ 9278f3d

Last change on this file since 9278f3d was 9278f3d, checked in by Sebastian Huber <sebastian.huber@…>, on 11/27/20 at 16:21:23

score: Canonicalize Doxygen @file comments

Use common phrases for the file brief descriptions.

Update #3706.

  • Property mode set to 100644
File size: 27.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief This header file provides the interfaces of the
5 *   @ref RTEMSScoreAtomicCPU.
6 */
7
8/*
9 * COPYRIGHT (c) 2013 Deng Hengyi.
10 * Copyright (c) 2015 embedded brains GmbH.
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#ifndef _RTEMS_SCORE_CPUSTDATOMIC_H
18#define _RTEMS_SCORE_CPUSTDATOMIC_H
19
20#include <rtems/score/basedefs.h>
21
22/**
23 * @defgroup RTEMSScoreAtomicCPU C11/C++11 Atomic Operations
24 *
25 * @ingroup RTEMSScoreAtomic
26 *
27 * @brief This group contains the atomic operations implementation using
28 *   functions provided by the C11/C++11.
29 *
30 * @{
31 */
32
33#ifdef RTEMS_SMP
34  #if defined(__cplusplus) \
35    && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
36    /*
37     * The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible.  The
38     * suggested solution was to include <atomic> in case C++ is used.  This works
39     * at least with GCC 4.9.  See also:
40     *
41     * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
42     * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940
43     */
44    #include <atomic>
45    #define _RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC
46  #else
47    #include <stdatomic.h>
48    #define _RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC
49  #endif
50#else
51  #include <rtems/score/isrlevel.h>
52#endif
53
54#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
55
56typedef std::atomic_uint CPU_atomic_Uint;
57
58typedef std::atomic_ulong CPU_atomic_Ulong;
59
60typedef std::atomic_uintptr_t CPU_atomic_Uintptr;
61
62typedef std::atomic_flag CPU_atomic_Flag;
63
64typedef std::memory_order CPU_atomic_Order;
65
66#define CPU_ATOMIC_ORDER_RELAXED std::memory_order_relaxed
67
68#define CPU_ATOMIC_ORDER_ACQUIRE std::memory_order_acquire
69
70#define CPU_ATOMIC_ORDER_RELEASE std::memory_order_release
71
72#define CPU_ATOMIC_ORDER_ACQ_REL std::memory_order_acq_rel
73
74#define CPU_ATOMIC_ORDER_SEQ_CST std::memory_order_seq_cst
75
76#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
77
78#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
79
80#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value )
81
82#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
83
84#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
85
86typedef atomic_uint CPU_atomic_Uint;
87
88typedef atomic_ulong CPU_atomic_Ulong;
89
90typedef atomic_uintptr_t CPU_atomic_Uintptr;
91
92typedef atomic_flag CPU_atomic_Flag;
93
94typedef memory_order CPU_atomic_Order;
95
96#define CPU_ATOMIC_ORDER_RELAXED memory_order_relaxed
97
98#define CPU_ATOMIC_ORDER_ACQUIRE memory_order_acquire
99
100#define CPU_ATOMIC_ORDER_RELEASE memory_order_release
101
102#define CPU_ATOMIC_ORDER_ACQ_REL memory_order_acq_rel
103
104#define CPU_ATOMIC_ORDER_SEQ_CST memory_order_seq_cst
105
106#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
107
108#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
109
110#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value )
111
112#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
113
114#else
115
116typedef unsigned int CPU_atomic_Uint;
117
118typedef unsigned long CPU_atomic_Ulong;
119
120typedef uintptr_t CPU_atomic_Uintptr;
121
122typedef bool CPU_atomic_Flag;
123
124typedef int CPU_atomic_Order;
125
126#define CPU_ATOMIC_ORDER_RELAXED 0
127
128#define CPU_ATOMIC_ORDER_ACQUIRE 2
129
130#define CPU_ATOMIC_ORDER_RELEASE 3
131
132#define CPU_ATOMIC_ORDER_ACQ_REL 4
133
134#define CPU_ATOMIC_ORDER_SEQ_CST 5
135
136#define CPU_ATOMIC_INITIALIZER_UINT( value ) ( value )
137
138#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ( value )
139
140#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ( value )
141
142#define CPU_ATOMIC_INITIALIZER_FLAG false
143
144#endif
145
146/**
147 * @brief Sets up a cpu fence.
148 *
149 * @param[out] order The order for the fence.
150 */
151static inline void _CPU_atomic_Fence( CPU_atomic_Order order )
152{
153#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
154  std::atomic_thread_fence( order );
155#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
156  atomic_thread_fence( order );
157#else
158  (void) order;
159  RTEMS_COMPILER_MEMORY_BARRIER();
160#endif
161}
162
163/**
164 * @brief Initializes Uint.
165 *
166 * @param[out] obj The CPU atomic Uint to initialize.
167 * @param desired The desired value for @a obj.
168 */
169static inline void _CPU_atomic_Init_uint( CPU_atomic_Uint *obj, unsigned int desired )
170{
171#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
172  obj->store( desired );
173#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
174  atomic_init( obj, desired );
175#else
176  *obj = desired;
177#endif
178}
179
180/**
181 * @brief Initializes Ulong.
182 *
183 * @param[out] obj The CPU atomic Ulong to initialize.
184 * @param desired The desired value for @a obj.
185 */
186static inline void _CPU_atomic_Init_ulong( CPU_atomic_Ulong *obj, unsigned long desired )
187{
188#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
189  obj->store( desired );
190#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
191  atomic_init( obj, desired );
192#else
193  *obj = desired;
194#endif
195}
196
197/**
198 * @brief Initializes Uintptr.
199 *
200 * @param[out] obj The CPU atomic Uintptr to initialize.
201 * @param desired The desired value for @a obj.
202 */
203static inline void _CPU_atomic_Init_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired )
204{
205#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
206  obj->store( desired );
207#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
208  atomic_init( obj, desired );
209#else
210  *obj = desired;
211#endif
212}
213
214/**
215 * @brief Loads value of Uint considering the order.
216 *
217 * @param obj The CPU atomic Uint to get the value from.
218 * @param order The atomic order for getting the value.
219 *
220 * @return The value of @a obj considering the @a order.
221 */
222static inline unsigned int _CPU_atomic_Load_uint( const CPU_atomic_Uint *obj, CPU_atomic_Order order )
223{
224#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
225  return obj->load( order );
226#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
227  return atomic_load_explicit( obj, order );
228#else
229  unsigned int val;
230
231  (void) order;
232  val = *obj;
233  RTEMS_COMPILER_MEMORY_BARRIER();
234
235  return val;
236#endif
237}
238
239/**
240 * @brief Loads value of Ulong considering the order.
241 *
242 * @param obj The CPU atomic Ulong to get the value from.
243 * @param order The atomic order for getting the value.
244 *
245 * @return The value of @a obj considering the @a order.
246 */
247static inline unsigned long _CPU_atomic_Load_ulong( const CPU_atomic_Ulong *obj, CPU_atomic_Order order )
248{
249#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
250  return obj->load( order );
251#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
252  return atomic_load_explicit( obj, order );
253#else
254  unsigned long val;
255
256  (void) order;
257  val = *obj;
258  RTEMS_COMPILER_MEMORY_BARRIER();
259
260  return val;
261#endif
262}
263
264/**
265 * @brief Loads value of Uintptr considering the order.
266 *
267 * @param obj The CPU atomic Uintptr to get the value from.
268 * @param order The atomic order for getting the value.
269 *
270 * @return The value of @a obj considering the @a order.
271 */
272static inline uintptr_t _CPU_atomic_Load_uintptr( const CPU_atomic_Uintptr *obj, CPU_atomic_Order order )
273{
274#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
275  return obj->load( order );
276#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
277  return atomic_load_explicit( obj, order );
278#else
279  uintptr_t val;
280
281  (void) order;
282  val = *obj;
283  RTEMS_COMPILER_MEMORY_BARRIER();
284
285  return val;
286#endif
287}
288
289/**
290 * @brief Stores a value to Uint considering the order.
291 *
292 * @param[out] obj The CPU atomic Uint to store a value in.
293 * @param desired The desired value for @a obj.
294 * @param order The atomic order for storing the value.
295 */
296static inline void _CPU_atomic_Store_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order )
297{
298#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
299  obj->store( desired );
300#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
301  atomic_store_explicit( obj, desired, order );
302#else
303  (void) order;
304  RTEMS_COMPILER_MEMORY_BARRIER();
305  *obj = desired;
306#endif
307}
308
309/**
310 * @brief Stores a value to Ulong considering the order.
311 *
312 * @param[out] obj The CPU atomic Ulong to store a value in.
313 * @param desired The desired value for @a obj.
314 * @param order The atomic order for storing the value.
315 */
316static inline void _CPU_atomic_Store_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order )
317{
318#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
319  obj->store( desired );
320#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
321  atomic_store_explicit( obj, desired, order );
322#else
323  (void) order;
324  RTEMS_COMPILER_MEMORY_BARRIER();
325  *obj = desired;
326#endif
327}
328
329/**
330 * @brief Stores a value to Uintptr considering the order.
331 *
332 * @param[out] obj The CPU atomic Uintptr to store a value in.
333 * @param desired The desired value for @a obj.
334 * @param order The atomic order for storing the value.
335 */
336static inline void _CPU_atomic_Store_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired, CPU_atomic_Order order )
337{
338#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
339  obj->store( desired );
340#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
341  atomic_store_explicit( obj, desired, order );
342#else
343  (void) order;
344  RTEMS_COMPILER_MEMORY_BARRIER();
345  *obj = desired;
346#endif
347}
348
349/**
350 * @brief Fetches current value of Uint and adds a value to the stored value.
351 *
352 * @param[in, out] obj The CPU atomic Uint to get the value from and add @a arg to.
353 * @param arg The value to add to @a obj.
354 * @param order The atomic order for the operation.
355 *
356 * @return The value of @a obj prior to the addition of @a arg.
357 */
358static inline unsigned int _CPU_atomic_Fetch_add_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
359{
360#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
361  return obj->fetch_add( arg, order );
362#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
363  return atomic_fetch_add_explicit( obj, arg, order );
364#else
365  unsigned int val;
366  ISR_Level level;
367
368  (void) order;
369  _ISR_Local_disable( level );
370  val = *obj;
371  *obj = val + arg;
372  _ISR_Local_enable( level );
373
374  return val;
375#endif
376}
377
378/**
379 * @brief Fetches current value of Ulong and adds a value to the stored value.
380 *
381 * @param[in, out] obj The CPU atomic Ulong to get the value from and add @a arg to.
382 * @param arg The value to add to @a obj.
383 * @param order The atomic order for the operation.
384 *
385 * @return The value of @a obj prior to the addition of @a arg.
386 */
387static inline unsigned long _CPU_atomic_Fetch_add_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
388{
389#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
390  return obj->fetch_add( arg, order );
391#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
392  return atomic_fetch_add_explicit( obj, arg, order );
393#else
394  unsigned long val;
395  ISR_Level level;
396
397  (void) order;
398  _ISR_Local_disable( level );
399  val = *obj;
400  *obj = val + arg;
401  _ISR_Local_enable( level );
402
403  return val;
404#endif
405}
406
407/**
408 * @brief Fetches current value of Uintptr and adds a value to the stored value.
409 *
410 * @param[in, out] obj The CPU atomic Uintptr to get the value from and add @a arg to.
411 * @param arg The value to add to @a obj.
412 * @param order The atomic order for the operation.
413 *
414 * @return The value of @a obj prior to the addition of @a arg.
415 */
416static inline uintptr_t _CPU_atomic_Fetch_add_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
417{
418#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
419  return obj->fetch_add( arg, order );
420#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
421  return atomic_fetch_add_explicit( obj, arg, order );
422#else
423  uintptr_t val;
424  ISR_Level level;
425
426  (void) order;
427  _ISR_Local_disable( level );
428  val = *obj;
429  *obj = val + arg;
430  _ISR_Local_enable( level );
431
432  return val;
433#endif
434}
435
436/**
437 * @brief Fetches current value of Uint and subtracts a value from the stored value.
438 *
439 * @param[in, out] obj The CPU atomic Uint to get the value from and subtract @a arg from.
440 * @param arg The value to subtract from @a obj.
441 * @param order The atomic order for the operation.
442 *
443 * @return The value of @a obj prior to the subtraction of @a arg.
444 */
445static inline unsigned int _CPU_atomic_Fetch_sub_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
446{
447#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
448  return obj->fetch_sub( arg, order );
449#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
450  return atomic_fetch_sub_explicit( obj, arg, order );
451#else
452  unsigned int val;
453  ISR_Level level;
454
455  (void) order;
456  _ISR_Local_disable( level );
457  val = *obj;
458  *obj = val - arg;
459  _ISR_Local_enable( level );
460
461  return val;
462#endif
463}
464
465/**
466 * @brief Fetches current value of Ulong and subtracts a value from the stored value.
467 *
468 * @param[in, out] obj The CPU atomic Ulong to get the value from and subtract @a arg from.
469 * @param arg The value to subtract from @a obj.
470 * @param order The atomic order for the operation.
471 *
472 * @return The value of @a obj prior to the subtraction of @a arg.
473 */
474static inline unsigned long _CPU_atomic_Fetch_sub_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
475{
476#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
477  return obj->fetch_sub( arg, order );
478#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
479  return atomic_fetch_sub_explicit( obj, arg, order );
480#else
481  unsigned long val;
482  ISR_Level level;
483
484  (void) order;
485  _ISR_Local_disable( level );
486  val = *obj;
487  *obj = val - arg;
488  _ISR_Local_enable( level );
489
490  return val;
491#endif
492}
493
494/**
495 * @brief Fetches current value of Uintptr and subtracts a value from the stored value.
496 *
497 * @param[in, out] obj The CPU atomic Uintptr to get the value from and subtract @a arg from.
498 * @param arg The value to subtract from @a obj.
499 * @param order The atomic order for the operation.
500 *
501 * @return The value of @a obj prior to the subtraction of @a arg.
502 */
503static inline uintptr_t _CPU_atomic_Fetch_sub_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
504{
505#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
506  return obj->fetch_sub( arg, order );
507#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
508  return atomic_fetch_sub_explicit( obj, arg, order );
509#else
510  uintptr_t val;
511  ISR_Level level;
512
513  (void) order;
514  _ISR_Local_disable( level );
515  val = *obj;
516  *obj = val - arg;
517  _ISR_Local_enable( level );
518
519  return val;
520#endif
521}
522
523/**
524 * @brief Fetches current value of Uint and ORs a value with the stored value.
525 *
526 * @param[in, out] obj The CPU atomic Uint to get the value from and OR @a arg to.
527 * @param arg The value to OR with @a obj.
528 * @param order The atomic order for the operation.
529 *
530 * @return The value of @a obj prior to the OR operation with @a arg.
531 */
532static inline unsigned int _CPU_atomic_Fetch_or_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
533{
534#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
535  return obj->fetch_or( arg, order );
536#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
537  return atomic_fetch_or_explicit( obj, arg, order );
538#else
539  unsigned int val;
540  ISR_Level level;
541
542  (void) order;
543  _ISR_Local_disable( level );
544  val = *obj;
545  *obj = val | arg;
546  _ISR_Local_enable( level );
547
548  return val;
549#endif
550}
551
552/**
553 * @brief Fetches current value of Ulong and ORs a value with the stored value.
554 *
555 * @param[in, out] obj The CPU atomic Ulong to get the value from and OR @a arg to.
556 * @param arg The value to OR with @a obj.
557 * @param order The atomic order for the operation.
558 *
559 * @return The value of @a obj prior to the OR operation with @a arg.
560 */
561static inline unsigned long _CPU_atomic_Fetch_or_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
562{
563#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
564  return obj->fetch_or( arg, order );
565#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
566  return atomic_fetch_or_explicit( obj, arg, order );
567#else
568  unsigned long val;
569  ISR_Level level;
570
571  (void) order;
572  _ISR_Local_disable( level );
573  val = *obj;
574  *obj = val | arg;
575  _ISR_Local_enable( level );
576
577  return val;
578#endif
579}
580
581/**
582 * @brief Fetches current value of Uintptr and ORs a value with the stored value.
583 *
584 * @param[in, out] obj The CPU atomic Uintptr to get the value from and OR @a arg to.
585 * @param arg The value to OR with @a obj.
586 * @param order The atomic order for the operation.
587 *
588 * @return The value of @a obj prior to the OR operation with @a arg.
589 */
590static inline uintptr_t _CPU_atomic_Fetch_or_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
591{
592#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
593  return obj->fetch_or( arg, order );
594#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
595  return atomic_fetch_or_explicit( obj, arg, order );
596#else
597  uintptr_t val;
598  ISR_Level level;
599
600  (void) order;
601  _ISR_Local_disable( level );
602  val = *obj;
603  *obj = val | arg;
604  _ISR_Local_enable( level );
605
606  return val;
607#endif
608}
609
610/**
611 * @brief Fetches current value of Uint and ANDs a value with the stored value.
612 *
613 * @param[in, out] obj The CPU atomic Uint to get the value from and AND @a arg to.
614 * @param arg The value to AND with @a obj.
615 * @param order The atomic order for the operation.
616 *
617 * @return The value of @a obj prior to the AND operation with @a arg.
618 */
619static inline unsigned int _CPU_atomic_Fetch_and_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
620{
621#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
622  return obj->fetch_and( arg, order );
623#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
624  return atomic_fetch_and_explicit( obj, arg, order );
625#else
626  unsigned int val;
627  ISR_Level level;
628
629  (void) order;
630  _ISR_Local_disable( level );
631  val = *obj;
632  *obj = val & arg;
633  _ISR_Local_enable( level );
634
635  return val;
636#endif
637}
638
639/**
640 * @brief Fetches current value of Ulong and ANDs a value with the stored value.
641 *
642 * @param[in, out] obj The CPU atomic Ulong to get the value from and AND @a arg to.
643 * @param arg The value to AND with @a obj.
644 * @param order The atomic order for the operation.
645 *
646 * @return The value of @a obj prior to the AND operation with @a arg.
647 */
648static inline unsigned long _CPU_atomic_Fetch_and_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
649{
650#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
651  return obj->fetch_and( arg, order );
652#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
653  return atomic_fetch_and_explicit( obj, arg, order );
654#else
655  unsigned long val;
656  ISR_Level level;
657
658  (void) order;
659  _ISR_Local_disable( level );
660  val = *obj;
661  *obj = val & arg;
662  _ISR_Local_enable( level );
663
664  return val;
665#endif
666}
667
668/**
669 * @brief Fetches current value of Uintptr and ANDs a value with the stored value.
670 *
671 * @param[in, out] obj The CPU atomic Uintptr to get the value from and AND @a arg to.
672 * @param arg The value to AND with @a obj.
673 * @param order The atomic order for the operation.
674 *
675 * @return The value of @a obj prior to the AND operation with @a arg.
676 */
677static inline uintptr_t _CPU_atomic_Fetch_and_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
678{
679#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
680  return obj->fetch_and( arg, order );
681#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
682  return atomic_fetch_and_explicit( obj, arg, order );
683#else
684  uintptr_t val;
685  ISR_Level level;
686
687  (void) order;
688  _ISR_Local_disable( level );
689  val = *obj;
690  *obj = val & arg;
691  _ISR_Local_enable( level );
692
693  return val;
694#endif
695}
696
697/**
698 * @brief Fetches current value of Uint and sets its value.
699 *
700 * @param[in, out] obj The CPU atomic Uint to get the value from and set the value to @a desired.
701 * @param arg The value to set for @a obj.
702 * @param order The atomic order for the operation.
703 *
704 * @return The value of @a obj prior to the exchange with @a desired.
705 */
706static inline unsigned int _CPU_atomic_Exchange_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order )
707{
708#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
709  return obj->exchange( desired, order );
710#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
711  return atomic_exchange_explicit( obj, desired, order );
712#else
713  unsigned int val;
714  ISR_Level level;
715
716  (void) order;
717  _ISR_Local_disable( level );
718  val = *obj;
719  *obj = desired;
720  _ISR_Local_enable( level );
721
722  return val;
723#endif
724}
725
726/**
727 * @brief Fetches current value of Ulong and sets its value.
728 *
729 * @param[in, out] obj The CPU atomic Ulong to get the value from and set the value to @a desired.
730 * @param arg The value to set for @a obj.
731 * @param order The atomic order for the operation.
732 *
733 * @return The value of @a obj prior to the exchange with @a desired.
734 */
735static inline unsigned long _CPU_atomic_Exchange_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order )
736{
737#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
738  return obj->exchange( desired, order );
739#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
740  return atomic_exchange_explicit( obj, desired, order );
741#else
742  unsigned long val;
743  ISR_Level level;
744
745  (void) order;
746  _ISR_Local_disable( level );
747  val = *obj;
748  *obj = desired;
749  _ISR_Local_enable( level );
750
751  return val;
752#endif
753}
754
755/**
756 * @brief Fetches current value of Uintptr and sets its value.
757 *
758 * @param[in, out] obj The CPU atomic Uintptr to get the value from and set the value to @a desired.
759 * @param arg The value to set for @a obj.
760 * @param order The atomic order for the operation.
761 *
762 * @return The value of @a obj prior to the exchange with @a desired.
763 */
764static inline uintptr_t _CPU_atomic_Exchange_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired, CPU_atomic_Order order )
765{
766#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
767  return obj->exchange( desired, order );
768#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
769  return atomic_exchange_explicit( obj, desired, order );
770#else
771  uintptr_t val;
772  ISR_Level level;
773
774  (void) order;
775  _ISR_Local_disable( level );
776  val = *obj;
777  *obj = desired;
778  _ISR_Local_enable( level );
779
780  return val;
781#endif
782}
783
784/**
785 * @brief Checks if value of Uint is as expected.
786 *
787 * This method checks if the value of @a obj is equal to the value of @a expected.  If
788 * this is the case, the value of @a obj is changed to @a desired.  Otherwise, the value
789 * of @a obj is changed to @a expected.
790 *
791 * @param[in, out] obj The CPU atomic Uint to operate upon.
792 * @param[in, out] expected The expected value of @a obj.  If @a obj has a different
793 *      value, @a expected is changed to the actual value of @a obj.
794 * @param desired The new value of @a obj if the old value of @a obj was as expected.
795 * @param succ The order if it is successful.
796 * @param fail The order if it fails.
797 *
798 * @retval true The old value of @a obj was as expected.
799 * @retval false The old value of @a obj was not as expected.
800 */
801static inline bool _CPU_atomic_Compare_exchange_uint( CPU_atomic_Uint *obj, unsigned int *expected, unsigned int desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
802{
803#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
804  return obj->compare_exchange_strong( *expected, desired, succ, fail );
805#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
806  return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
807#else
808  bool success;
809  ISR_Level level;
810  unsigned int actual;
811
812  (void) succ;
813  (void) fail;
814  _ISR_Local_disable( level );
815  actual = *obj;
816  success = ( actual == *expected );
817  if ( success ) {
818    *obj = desired;
819  } else {
820    *expected = actual;
821  }
822  _ISR_Local_enable( level );
823
824  return success;
825#endif
826}
827
828/**
829 * @brief Checks if value of Ulong is as expected.
830 *
831 * This method checks if the value of @a obj is equal to the value of @a expected.  If
832 * this is the case, the value of @a obj is changed to @a desired.  Otherwise, the value
833 * of @a obj is changed to @a expected.
834 *
835 * @param[in, out] obj The CPU atomic Ulong to operate upon.
836 * @param[in, out] expected The expected value of @a obj.  If @a obj has a different
837 *      value, @a expected is changed to the actual value of @a obj.
838 * @param desired The new value of @a obj if the old value of @a obj was as expected.
839 * @param succ The order if it is successful.
840 * @param fail The order if it fails.
841 *
842 * @retval true The old value of @a obj was as expected.
843 * @retval false The old value of @a obj was not as expected.
844 */
845static inline bool _CPU_atomic_Compare_exchange_ulong( CPU_atomic_Ulong *obj, unsigned long *expected, unsigned long desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
846{
847#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
848  return obj->compare_exchange_strong( *expected, desired, succ, fail );
849#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
850  return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
851#else
852  bool success;
853  ISR_Level level;
854  unsigned long actual;
855
856  (void) succ;
857  (void) fail;
858  _ISR_Local_disable( level );
859  actual = *obj;
860  success = ( actual == *expected );
861  if ( success ) {
862    *obj = desired;
863  } else {
864    *expected = actual;
865  }
866  _ISR_Local_enable( level );
867
868  return success;
869#endif
870}
871
872/**
873 * @brief Checks if value of Uintptr is as expected.
874 *
875 * This method checks if the value of @a obj is equal to the value of @a expected.  If
876 * this is the case, the value of @a obj is changed to @a desired.  Otherwise, the value
877 * of @a obj is changed to @a expected.
878 *
879 * @param[in, out] obj The CPU atomic Uintptr to operate upon.
880 * @param[in, out] expected The expected value of @a obj.  If @a obj has a different
881 *      value, @a expected is changed to the actual value of @a obj.
882 * @param desired The new value of @a obj if the old value of @a obj was as expected.
883 * @param succ The order if it is successful.
884 * @param fail The order if it fails.
885 *
886 * @retval true The old value of @a obj was as expected.
887 * @retval false The old value of @a obj was not as expected.
888 */
889static inline bool _CPU_atomic_Compare_exchange_uintptr( CPU_atomic_Uintptr *obj, uintptr_t *expected, uintptr_t desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
890{
891#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
892  return obj->compare_exchange_strong( *expected, desired, succ, fail );
893#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
894  return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
895#else
896  bool success;
897  ISR_Level level;
898  uintptr_t actual;
899
900  (void) succ;
901  (void) fail;
902  _ISR_Local_disable( level );
903  actual = *obj;
904  success = ( actual == *expected );
905  if ( success ) {
906    *obj = desired;
907  } else {
908    *expected = actual;
909  }
910  _ISR_Local_enable( level );
911
912  return success;
913#endif
914}
915
916/**
917 * @brief Clears the atomic flag.
918 *
919 * @param[out] obj The atomic flag to be cleared.
920 * @param order The atomic order for the operation.
921 */
922static inline void _CPU_atomic_Flag_clear( CPU_atomic_Flag *obj, CPU_atomic_Order order )
923{
924#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
925  obj->clear( order );
926#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
927  atomic_flag_clear_explicit( obj, order );
928#else
929  (void) order;
930  *obj = false;
931#endif
932}
933
934/**
935 * @brief Returns current flag state and sets it.
936 *
937 * @param[in, out] obj The atomic flag to be set.
938 * @param order The atomic order for the operation.
939 *
940 * @retval true @a obj was set prior to this operation.
941 * @retval false @a obj was not set prior to this operation.
942 */
943static inline bool _CPU_atomic_Flag_test_and_set( CPU_atomic_Flag *obj, CPU_atomic_Order order )
944{
945#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
946  return obj->test_and_set( order );
947#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
948  return atomic_flag_test_and_set_explicit( obj, order );
949#else
950  bool flag;
951  ISR_Level level;
952
953  (void) order;
954  _ISR_Local_disable( level );
955  flag = *obj;
956  *obj = true;
957  _ISR_Local_enable( level );
958
959  return flag;
960#endif
961}
962
963/** @} */
964
965#endif /* _RTEMS_SCORE_CPUSTDATOMIC_H */
Note: See TracBrowser for help on using the repository browser.