/ duct-tape / xnu / EXTERNAL_HEADERS / stdatomic.h
stdatomic.h
  1  /*===---- stdatomic.h - Standard header for atomic types and operations -----===
  2   *
  3   * Permission is hereby granted, free of charge, to any person obtaining a copy
  4   * of this software and associated documentation files (the "Software"), to deal
  5   * in the Software without restriction, including without limitation the rights
  6   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7   * copies of the Software, and to permit persons to whom the Software is
  8   * furnished to do so, subject to the following conditions:
  9   *
 10   * The above copyright notice and this permission notice shall be included in
 11   * all copies or substantial portions of the Software.
 12   *
 13   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 14   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 15   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 16   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 17   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 18   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 19   * THE SOFTWARE.
 20   *
 21   *===-----------------------------------------------------------------------===
 22   */
 23  
 24  #ifndef __clang__
 25  #error unsupported compiler
 26  #endif
 27  
 28  #ifndef __CLANG_STDATOMIC_H
 29  #define __CLANG_STDATOMIC_H
 30  
 31  /* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for
 32   * example, already has a Clang-compatible stdatomic.h header.
 33   */
 34  #if __STDC_HOSTED__ && __has_include_next(<stdatomic.h>) && !defined(__DARLING__)
 35  # include_next <stdatomic.h>
 36  #else
 37  
 38  #include <stddef.h>
 39  #include <stdint.h>
 40  
 41  #ifdef __cplusplus
 42  extern "C" {
 43  #endif
 44  
 45  /* 7.17.1 Introduction */
 46  
 47  #define ATOMIC_BOOL_LOCK_FREE       __CLANG_ATOMIC_BOOL_LOCK_FREE
 48  #define ATOMIC_CHAR_LOCK_FREE       __CLANG_ATOMIC_CHAR_LOCK_FREE
 49  #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 50  #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 51  #define ATOMIC_WCHAR_T_LOCK_FREE    __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
 52  #define ATOMIC_SHORT_LOCK_FREE      __CLANG_ATOMIC_SHORT_LOCK_FREE
 53  #define ATOMIC_INT_LOCK_FREE        __CLANG_ATOMIC_INT_LOCK_FREE
 54  #define ATOMIC_LONG_LOCK_FREE       __CLANG_ATOMIC_LONG_LOCK_FREE
 55  #define ATOMIC_LLONG_LOCK_FREE      __CLANG_ATOMIC_LLONG_LOCK_FREE
 56  #define ATOMIC_POINTER_LOCK_FREE    __CLANG_ATOMIC_POINTER_LOCK_FREE
 57  
 58  /* 7.17.2 Initialization */
 59  
 60  #define ATOMIC_VAR_INIT(value) (value)
 61  #define atomic_init __c11_atomic_init
 62  
 63  /* 7.17.3 Order and consistency */
 64  
 65  typedef enum memory_order {
 66    memory_order_relaxed = __ATOMIC_RELAXED,
 67    memory_order_consume = __ATOMIC_CONSUME,
 68    memory_order_acquire = __ATOMIC_ACQUIRE,
 69    memory_order_release = __ATOMIC_RELEASE,
 70    memory_order_acq_rel = __ATOMIC_ACQ_REL,
 71    memory_order_seq_cst = __ATOMIC_SEQ_CST
 72  } memory_order;
 73  
 74  #define kill_dependency(y) (y)
 75  
 76  /* 7.17.4 Fences */
 77  
 78  #ifndef KERNEL
 79  /* These should be provided by the libc implementation. */
 80  void atomic_thread_fence(memory_order);
 81  void atomic_signal_fence(memory_order);
 82  #endif
 83  
 84  #define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
 85  #define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
 86  
 87  /* 7.17.5 Lock-free property */
 88  
 89  #define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
 90  
 91  /* 7.17.6 Atomic integer types */
 92  
 93  #ifdef __cplusplus
 94  typedef _Atomic(bool)               atomic_bool;
 95  #else
 96  typedef _Atomic(_Bool)              atomic_bool;
 97  #endif
 98  typedef _Atomic(char)               atomic_char;
 99  typedef _Atomic(signed char)        atomic_schar;
100  typedef _Atomic(unsigned char)      atomic_uchar;
101  typedef _Atomic(short)              atomic_short;
102  typedef _Atomic(unsigned short)     atomic_ushort;
103  typedef _Atomic(int)                atomic_int;
104  typedef _Atomic(unsigned int)       atomic_uint;
105  typedef _Atomic(long)               atomic_long;
106  typedef _Atomic(unsigned long)      atomic_ulong;
107  typedef _Atomic(long long)          atomic_llong;
108  typedef _Atomic(unsigned long long) atomic_ullong;
109  typedef _Atomic(uint_least16_t)     atomic_char16_t;
110  typedef _Atomic(uint_least32_t)     atomic_char32_t;
111  typedef _Atomic(wchar_t)            atomic_wchar_t;
112  typedef _Atomic(int_least8_t)       atomic_int_least8_t;
113  typedef _Atomic(uint_least8_t)      atomic_uint_least8_t;
114  typedef _Atomic(int_least16_t)      atomic_int_least16_t;
115  typedef _Atomic(uint_least16_t)     atomic_uint_least16_t;
116  typedef _Atomic(int_least32_t)      atomic_int_least32_t;
117  typedef _Atomic(uint_least32_t)     atomic_uint_least32_t;
118  typedef _Atomic(int_least64_t)      atomic_int_least64_t;
119  typedef _Atomic(uint_least64_t)     atomic_uint_least64_t;
120  typedef _Atomic(int_fast8_t)        atomic_int_fast8_t;
121  typedef _Atomic(uint_fast8_t)       atomic_uint_fast8_t;
122  typedef _Atomic(int_fast16_t)       atomic_int_fast16_t;
123  typedef _Atomic(uint_fast16_t)      atomic_uint_fast16_t;
124  typedef _Atomic(int_fast32_t)       atomic_int_fast32_t;
125  typedef _Atomic(uint_fast32_t)      atomic_uint_fast32_t;
126  typedef _Atomic(int_fast64_t)       atomic_int_fast64_t;
127  typedef _Atomic(uint_fast64_t)      atomic_uint_fast64_t;
128  typedef _Atomic(intptr_t)           atomic_intptr_t;
129  typedef _Atomic(uintptr_t)          atomic_uintptr_t;
130  typedef _Atomic(size_t)             atomic_size_t;
131  typedef _Atomic(ptrdiff_t)          atomic_ptrdiff_t;
132  typedef _Atomic(intmax_t)           atomic_intmax_t;
133  typedef _Atomic(uintmax_t)          atomic_uintmax_t;
134  
135  /* 7.17.7 Operations on atomic types */
136  
137  #define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
138  #define atomic_store_explicit __c11_atomic_store
139  
140  #define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
141  #define atomic_load_explicit __c11_atomic_load
142  
143  #define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
144  #define atomic_exchange_explicit __c11_atomic_exchange
145  
146  #define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
147  #define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
148  
149  #define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
150  #define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
151  
152  #define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
153  #define atomic_fetch_add_explicit __c11_atomic_fetch_add
154  
155  #define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
156  #define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
157  
158  #define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
159  #define atomic_fetch_or_explicit __c11_atomic_fetch_or
160  
161  #define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
162  #define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
163  
164  #define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
165  #define atomic_fetch_and_explicit __c11_atomic_fetch_and
166  
167  /* 7.17.8 Atomic flag type and operations */
168  
169  typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
170  
171  #define ATOMIC_FLAG_INIT { 0 }
172  
173  #ifndef KERNEL
174  /* These should be provided by the libc implementation. */
175  #ifdef __cplusplus
176  bool atomic_flag_test_and_set(volatile atomic_flag *);
177  bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
178  #else
179  _Bool atomic_flag_test_and_set(volatile atomic_flag *);
180  _Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
181  #endif
182  void atomic_flag_clear(volatile atomic_flag *);
183  void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order);
184  #endif
185  
186  #define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST)
187  #define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order)
188  
189  #define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST)
190  #define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order)
191  
192  #ifdef __cplusplus
193  }
194  #endif
195  
196  #endif /* __STDC_HOSTED__ */
197  #endif /* __CLANG_STDATOMIC_H */
198