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