C2x was finalized at the June 2023 WG14 meeting. The DIS is out for balloting and the comment period for that closes later this year/early next year. While that does leave an opportunity for more changes to the standard during the DIS ballot resolution process, only editorial changes are anticipated and as a result, the C committee considers C2x to be final. The committee took a straw poll on what we'd prefer the informal name of the standard be, and we decided it should be called C23 regardless of what year ISO publishes it. However, because the final publication is not out, this patch does not add the language standard alias for the -std=iso9899:<year> spelling of the standard mode; that will be added once ISO finally publishes the document and the year chosen will match the publication date. This also changes the value of __STDC_VERSION__ from the placeholder value 202000L to the final value 202311L. Subsequent patches will start renaming things from c2x to c23, cleaning up documentation, etc. Differential Revision: https://reviews.llvm.org/D157606
195 lines
8.1 KiB
C++
195 lines
8.1 KiB
C++
/*===---- stdatomic.h - Standard header for atomic types and operations -----===
|
|
*
|
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
* See https://llvm.org/LICENSE.txt for license information.
|
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
*
|
|
*===-----------------------------------------------------------------------===
|
|
*/
|
|
|
|
#ifndef __CLANG_STDATOMIC_H
|
|
#define __CLANG_STDATOMIC_H
|
|
|
|
/* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for
|
|
* example, already has a Clang-compatible stdatomic.h header.
|
|
*
|
|
* Exclude the MSVC path as well as the MSVC header as of the 14.31.30818
|
|
* explicitly disallows `stdatomic.h` in the C mode via an `#error`. Fallback
|
|
* to the clang resource header until that is fully supported. The
|
|
* `stdatomic.h` header requires C++ 23 or newer.
|
|
*/
|
|
#if __STDC_HOSTED__ && \
|
|
__has_include_next(<stdatomic.h>) && \
|
|
(!defined(_MSC_VER) || (defined(__cplusplus) && __cplusplus >= 202002L))
|
|
# include_next <stdatomic.h>
|
|
#else
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* 7.17.1 Introduction */
|
|
|
|
#define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
|
|
#define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
|
|
#define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
|
|
#define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
|
|
#define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
|
|
#define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
|
|
#define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
|
|
#define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
|
|
#define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
|
|
#define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
|
|
|
|
/* 7.17.2 Initialization */
|
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 202311L) || \
|
|
defined(__cplusplus)
|
|
/* ATOMIC_VAR_INIT was removed in C23, but still remains in C++23. */
|
|
#define ATOMIC_VAR_INIT(value) (value)
|
|
#endif
|
|
|
|
#if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L && \
|
|
__STDC_VERSION__ < 202311L) || \
|
|
(defined(__cplusplus) && __cplusplus >= 202002L)) && \
|
|
!defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS)
|
|
/* ATOMIC_VAR_INIT was deprecated in C17 and C++20. */
|
|
#pragma clang deprecated(ATOMIC_VAR_INIT)
|
|
#endif
|
|
#define atomic_init __c11_atomic_init
|
|
|
|
/* 7.17.3 Order and consistency */
|
|
|
|
typedef enum memory_order {
|
|
memory_order_relaxed = __ATOMIC_RELAXED,
|
|
memory_order_consume = __ATOMIC_CONSUME,
|
|
memory_order_acquire = __ATOMIC_ACQUIRE,
|
|
memory_order_release = __ATOMIC_RELEASE,
|
|
memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
|
memory_order_seq_cst = __ATOMIC_SEQ_CST
|
|
} memory_order;
|
|
|
|
#define kill_dependency(y) (y)
|
|
|
|
/* 7.17.4 Fences */
|
|
|
|
/* These should be provided by the libc implementation. */
|
|
void atomic_thread_fence(memory_order);
|
|
void atomic_signal_fence(memory_order);
|
|
|
|
#define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
|
|
#define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
|
|
|
|
/* 7.17.5 Lock-free property */
|
|
|
|
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
|
|
|
|
/* 7.17.6 Atomic integer types */
|
|
|
|
#ifdef __cplusplus
|
|
typedef _Atomic(bool) atomic_bool;
|
|
#else
|
|
typedef _Atomic(_Bool) atomic_bool;
|
|
#endif
|
|
typedef _Atomic(char) atomic_char;
|
|
typedef _Atomic(signed char) atomic_schar;
|
|
typedef _Atomic(unsigned char) atomic_uchar;
|
|
typedef _Atomic(short) atomic_short;
|
|
typedef _Atomic(unsigned short) atomic_ushort;
|
|
typedef _Atomic(int) atomic_int;
|
|
typedef _Atomic(unsigned int) atomic_uint;
|
|
typedef _Atomic(long) atomic_long;
|
|
typedef _Atomic(unsigned long) atomic_ulong;
|
|
typedef _Atomic(long long) atomic_llong;
|
|
typedef _Atomic(unsigned long long) atomic_ullong;
|
|
typedef _Atomic(uint_least16_t) atomic_char16_t;
|
|
typedef _Atomic(uint_least32_t) atomic_char32_t;
|
|
typedef _Atomic(wchar_t) atomic_wchar_t;
|
|
typedef _Atomic(int_least8_t) atomic_int_least8_t;
|
|
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
|
|
typedef _Atomic(int_least16_t) atomic_int_least16_t;
|
|
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
|
|
typedef _Atomic(int_least32_t) atomic_int_least32_t;
|
|
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
|
|
typedef _Atomic(int_least64_t) atomic_int_least64_t;
|
|
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
|
|
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
|
|
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
|
|
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
|
|
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
|
|
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
|
|
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
|
|
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
|
|
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
|
|
typedef _Atomic(intptr_t) atomic_intptr_t;
|
|
typedef _Atomic(uintptr_t) atomic_uintptr_t;
|
|
typedef _Atomic(size_t) atomic_size_t;
|
|
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
|
|
typedef _Atomic(intmax_t) atomic_intmax_t;
|
|
typedef _Atomic(uintmax_t) atomic_uintmax_t;
|
|
|
|
/* 7.17.7 Operations on atomic types */
|
|
|
|
#define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
|
|
#define atomic_store_explicit __c11_atomic_store
|
|
|
|
#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
|
|
#define atomic_load_explicit __c11_atomic_load
|
|
|
|
#define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
|
|
#define atomic_exchange_explicit __c11_atomic_exchange
|
|
|
|
#define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
|
#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
|
|
|
|
#define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
|
#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
|
|
|
|
#define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
|
|
#define atomic_fetch_add_explicit __c11_atomic_fetch_add
|
|
|
|
#define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
|
|
#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
|
|
|
|
#define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
|
|
#define atomic_fetch_or_explicit __c11_atomic_fetch_or
|
|
|
|
#define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
|
|
#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
|
|
|
|
#define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
|
|
#define atomic_fetch_and_explicit __c11_atomic_fetch_and
|
|
|
|
/* 7.17.8 Atomic flag type and operations */
|
|
|
|
typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
|
|
|
|
#define ATOMIC_FLAG_INIT { 0 }
|
|
|
|
/* These should be provided by the libc implementation. */
|
|
#ifdef __cplusplus
|
|
bool atomic_flag_test_and_set(volatile atomic_flag *);
|
|
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
|
|
#else
|
|
_Bool atomic_flag_test_and_set(volatile atomic_flag *);
|
|
_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
|
|
#endif
|
|
void atomic_flag_clear(volatile atomic_flag *);
|
|
void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order);
|
|
|
|
#define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST)
|
|
#define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order)
|
|
|
|
#define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST)
|
|
#define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __STDC_HOSTED__ */
|
|
#endif /* __CLANG_STDATOMIC_H */
|
|
|