kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

stdatomic.h (8135B)


      1 /* stdatomic.h -- C11 7.17 -- Atomics
      2  *
      3  * Atomic codegen, lock-free shape, and fence semantics are entirely
      4  * target-defined, so this header is a thin C11 surface over kit's
      5  * atomic builtins. The `__atomic_*` family operates transparently on
      6  * `_Atomic`-qualified pointers; lock-free properties come from the
      7  * `__ATOMIC_*_LOCK_FREE` macros.
      8  */
      9 #ifndef KIT_STDATOMIC_H
     10 #define KIT_STDATOMIC_H
     11 
     12 #include <stddef.h>
     13 #include <stdint.h>
     14 
     15 /* ------------------------------------------------------------------ */
     16 /* 7.17.3  Order and consistency                                      */
     17 /* ------------------------------------------------------------------ */
     18 typedef enum memory_order {
     19   memory_order_relaxed = __ATOMIC_RELAXED,
     20   memory_order_consume = __ATOMIC_CONSUME,
     21   memory_order_acquire = __ATOMIC_ACQUIRE,
     22   memory_order_release = __ATOMIC_RELEASE,
     23   memory_order_acq_rel = __ATOMIC_ACQ_REL,
     24   memory_order_seq_cst = __ATOMIC_SEQ_CST,
     25 } memory_order;
     26 
     27 #define kill_dependency(y) (y)
     28 
     29 /* ------------------------------------------------------------------ */
     30 /* 7.17.1  Lock-free property macros                                  */
     31 /* ------------------------------------------------------------------ */
     32 #define ATOMIC_BOOL_LOCK_FREE __ATOMIC_BOOL_LOCK_FREE
     33 #define ATOMIC_CHAR_LOCK_FREE __ATOMIC_CHAR_LOCK_FREE
     34 #define ATOMIC_CHAR16_T_LOCK_FREE __ATOMIC_CHAR16_T_LOCK_FREE
     35 #define ATOMIC_CHAR32_T_LOCK_FREE __ATOMIC_CHAR32_T_LOCK_FREE
     36 #define ATOMIC_WCHAR_T_LOCK_FREE __ATOMIC_WCHAR_T_LOCK_FREE
     37 #define ATOMIC_SHORT_LOCK_FREE __ATOMIC_SHORT_LOCK_FREE
     38 #define ATOMIC_INT_LOCK_FREE __ATOMIC_INT_LOCK_FREE
     39 #define ATOMIC_LONG_LOCK_FREE __ATOMIC_LONG_LOCK_FREE
     40 #define ATOMIC_LLONG_LOCK_FREE __ATOMIC_LLONG_LOCK_FREE
     41 #define ATOMIC_POINTER_LOCK_FREE __ATOMIC_POINTER_LOCK_FREE
     42 
     43 /* ------------------------------------------------------------------ */
     44 /* 7.17.2  Initialization                                             */
     45 /* ------------------------------------------------------------------ */
     46 #define ATOMIC_VAR_INIT(value) (value)
     47 #define atomic_init(obj, value) \
     48   __atomic_store_n((obj), (value), __ATOMIC_RELAXED)
     49 
     50 /* ------------------------------------------------------------------ */
     51 /* 7.17.4  Fences                                                     */
     52 /* ------------------------------------------------------------------ */
     53 #define atomic_thread_fence(order) __atomic_thread_fence(order)
     54 #define atomic_signal_fence(order) __atomic_signal_fence(order)
     55 
     56 /* ------------------------------------------------------------------ */
     57 /* 7.17.5  Lock-free property query                                   */
     58 /* ------------------------------------------------------------------ */
     59 #define atomic_is_lock_free(obj) __atomic_is_lock_free(sizeof(*(obj)), (obj))
     60 
     61 /* ------------------------------------------------------------------ */
     62 /* 7.17.6  Atomic integer types                                       */
     63 /* ------------------------------------------------------------------ */
     64 typedef _Atomic _Bool atomic_bool;
     65 typedef _Atomic char atomic_char;
     66 typedef _Atomic signed char atomic_schar;
     67 typedef _Atomic unsigned char atomic_uchar;
     68 typedef _Atomic short atomic_short;
     69 typedef _Atomic unsigned short atomic_ushort;
     70 typedef _Atomic int atomic_int;
     71 typedef _Atomic unsigned int atomic_uint;
     72 typedef _Atomic long atomic_long;
     73 typedef _Atomic unsigned long atomic_ulong;
     74 typedef _Atomic long long atomic_llong;
     75 typedef _Atomic unsigned long long atomic_ullong;
     76 typedef _Atomic __CHAR16_TYPE__ atomic_char16_t;
     77 typedef _Atomic __CHAR32_TYPE__ atomic_char32_t;
     78 typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t;
     79 typedef _Atomic int_least8_t atomic_int_least8_t;
     80 typedef _Atomic uint_least8_t atomic_uint_least8_t;
     81 typedef _Atomic int_least16_t atomic_int_least16_t;
     82 typedef _Atomic uint_least16_t atomic_uint_least16_t;
     83 typedef _Atomic int_least32_t atomic_int_least32_t;
     84 typedef _Atomic uint_least32_t atomic_uint_least32_t;
     85 typedef _Atomic int_least64_t atomic_int_least64_t;
     86 typedef _Atomic uint_least64_t atomic_uint_least64_t;
     87 typedef _Atomic int_fast8_t atomic_int_fast8_t;
     88 typedef _Atomic uint_fast8_t atomic_uint_fast8_t;
     89 typedef _Atomic int_fast16_t atomic_int_fast16_t;
     90 typedef _Atomic uint_fast16_t atomic_uint_fast16_t;
     91 typedef _Atomic int_fast32_t atomic_int_fast32_t;
     92 typedef _Atomic uint_fast32_t atomic_uint_fast32_t;
     93 typedef _Atomic int_fast64_t atomic_int_fast64_t;
     94 typedef _Atomic uint_fast64_t atomic_uint_fast64_t;
     95 typedef _Atomic intptr_t atomic_intptr_t;
     96 typedef _Atomic uintptr_t atomic_uintptr_t;
     97 typedef _Atomic size_t atomic_size_t;
     98 typedef _Atomic ptrdiff_t atomic_ptrdiff_t;
     99 typedef _Atomic intmax_t atomic_intmax_t;
    100 typedef _Atomic uintmax_t atomic_uintmax_t;
    101 
    102 /* ------------------------------------------------------------------ */
    103 /* 7.17.7  Operations on atomic types                                 */
    104 /* ------------------------------------------------------------------ */
    105 #define atomic_store(obj, desired) \
    106   __atomic_store_n((obj), (desired), __ATOMIC_SEQ_CST)
    107 #define atomic_store_explicit(obj, desired, order) \
    108   __atomic_store_n((obj), (desired), (order))
    109 
    110 #define atomic_load(obj) __atomic_load_n((obj), __ATOMIC_SEQ_CST)
    111 #define atomic_load_explicit(obj, order) __atomic_load_n((obj), (order))
    112 
    113 #define atomic_exchange(obj, desired) \
    114   __atomic_exchange_n((obj), (desired), __ATOMIC_SEQ_CST)
    115 #define atomic_exchange_explicit(obj, desired, order) \
    116   __atomic_exchange_n((obj), (desired), (order))
    117 
    118 #define atomic_compare_exchange_strong(obj, expected, desired) \
    119   __atomic_compare_exchange_n((obj), (expected), (desired), 0, \
    120                               __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
    121 #define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \
    122                                                 fail)                         \
    123   __atomic_compare_exchange_n((obj), (expected), (desired), 0, (succ), (fail))
    124 #define atomic_compare_exchange_weak(obj, expected, desired)   \
    125   __atomic_compare_exchange_n((obj), (expected), (desired), 1, \
    126                               __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
    127 #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \
    128                                               fail)                         \
    129   __atomic_compare_exchange_n((obj), (expected), (desired), 1, (succ), (fail))
    130 
    131 #define atomic_fetch_add(obj, arg) \
    132   __atomic_fetch_add((obj), (arg), __ATOMIC_SEQ_CST)
    133 #define atomic_fetch_add_explicit(obj, arg, order) \
    134   __atomic_fetch_add((obj), (arg), (order))
    135 #define atomic_fetch_sub(obj, arg) \
    136   __atomic_fetch_sub((obj), (arg), __ATOMIC_SEQ_CST)
    137 #define atomic_fetch_sub_explicit(obj, arg, order) \
    138   __atomic_fetch_sub((obj), (arg), (order))
    139 #define atomic_fetch_or(obj, arg) \
    140   __atomic_fetch_or((obj), (arg), __ATOMIC_SEQ_CST)
    141 #define atomic_fetch_or_explicit(obj, arg, order) \
    142   __atomic_fetch_or((obj), (arg), (order))
    143 #define atomic_fetch_xor(obj, arg) \
    144   __atomic_fetch_xor((obj), (arg), __ATOMIC_SEQ_CST)
    145 #define atomic_fetch_xor_explicit(obj, arg, order) \
    146   __atomic_fetch_xor((obj), (arg), (order))
    147 #define atomic_fetch_and(obj, arg) \
    148   __atomic_fetch_and((obj), (arg), __ATOMIC_SEQ_CST)
    149 #define atomic_fetch_and_explicit(obj, arg, order) \
    150   __atomic_fetch_and((obj), (arg), (order))
    151 
    152 /* ------------------------------------------------------------------ */
    153 /* 7.17.8  Atomic flag                                                */
    154 /* ------------------------------------------------------------------ */
    155 typedef struct atomic_flag {
    156   /* Opaque flag storage may be wider than _Bool; use a word-sized atomic so
    157      every primary backend can implement test-and-set with native RMW width. */
    158   _Atomic unsigned int _Value;
    159 } atomic_flag;
    160 
    161 #define ATOMIC_FLAG_INIT {0}
    162 
    163 #define atomic_flag_test_and_set(obj) \
    164   __atomic_exchange_n(&(obj)->_Value, 1, __ATOMIC_SEQ_CST)
    165 #define atomic_flag_test_and_set_explicit(obj, order) \
    166   __atomic_exchange_n(&(obj)->_Value, 1, (order))
    167 #define atomic_flag_clear(obj) \
    168   __atomic_store_n(&(obj)->_Value, 0, __ATOMIC_SEQ_CST)
    169 #define atomic_flag_clear_explicit(obj, order) \
    170   __atomic_store_n(&(obj)->_Value, 0, (order))
    171 
    172 #endif