feat(headers): stddef/stdint/stdbool/limits/float/assert + features wiring
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
#ifndef VLIBC_STDATOMIC_H
|
||||
#define VLIBC_STDATOMIC_H
|
||||
|
||||
/*
|
||||
* vlibc — <stdatomic.h>.
|
||||
*
|
||||
* Atomics (C23). All operations defer to the GCC __atomic_* builtins, the
|
||||
* same idiom src/internal/atomic.h uses: on x86_64 every standard atomic
|
||||
* type here is lock-free in hardware, so the builtins inline to plain
|
||||
* instructions and never call into libatomic. The header is fully
|
||||
* self-contained (no system stdatomic.h) and compiles as C17-style code too,
|
||||
* since _Atomic remains a keyword.
|
||||
*
|
||||
* The atomic_* operations are function-like macros over the polymorphic
|
||||
* builtins (C23 allows any atomic operation to be implemented as a macro),
|
||||
* which keeps them type-generic across every atomic_* type without a
|
||||
* _Generic dispatch table.
|
||||
*
|
||||
* This header is ISO C core and is present in every profile.
|
||||
*/
|
||||
|
||||
#include <vlibc/features.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Memory ordering. The enum values are the GCC __ATOMIC_* constants. */
|
||||
typedef enum
|
||||
{
|
||||
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;
|
||||
|
||||
/* Lock-free guarantees for each type (0: never, 1: sometimes, 2: always). */
|
||||
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
|
||||
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
|
||||
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
|
||||
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
|
||||
#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
|
||||
#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
|
||||
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
|
||||
|
||||
/* Atomic scalar types. */
|
||||
typedef _Atomic _Bool atomic_bool;
|
||||
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 __CHAR16_TYPE__ atomic_char16_t;
|
||||
typedef _Atomic __CHAR32_TYPE__ atomic_char32_t;
|
||||
typedef _Atomic __WCHAR_TYPE__ 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;
|
||||
|
||||
/* The only type the standard guarantees to be lock-free. */
|
||||
typedef _Atomic unsigned int atomic_flag;
|
||||
|
||||
/* Initializer for an atomic_flag object. */
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
/*
|
||||
* The operations below are macros because the __atomic_* builtins are
|
||||
* polymorphic: they accept any 1/2/4/8-byte scalar or pointer type, so a
|
||||
* single macro serves every atomic_* type. The (object) argument is the
|
||||
* address of the atomic object, matching the standard's function signatures.
|
||||
*/
|
||||
|
||||
/* Initialize the atomic object to value (a relaxed store). */
|
||||
#define atomic_init(object, value) __atomic_store_n((object), (value), __ATOMIC_RELAXED)
|
||||
|
||||
/* Load the current value. */
|
||||
#define atomic_load(object) __atomic_load_n((object), __ATOMIC_SEQ_CST)
|
||||
#define atomic_load_explicit(object, order) __atomic_load_n((object), (order))
|
||||
|
||||
/* Store value. */
|
||||
#define atomic_store(object, value) __atomic_store_n((object), (value), __ATOMIC_SEQ_CST)
|
||||
#define atomic_store_explicit(object, value, order) __atomic_store_n((object), (value), (order))
|
||||
|
||||
/* Exchange object's value with desired; returns the previous value. */
|
||||
#define atomic_exchange(object, desired) __atomic_exchange_n((object), (desired), __ATOMIC_SEQ_CST)
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
__atomic_exchange_n((object), (desired), (order))
|
||||
|
||||
/*
|
||||
* Compare-and-swap: store desired into object iff *object equals *expected.
|
||||
* On failure *expected is updated with the actual value and the macro
|
||||
* returns false. The first memorder governs the read-modify-write on
|
||||
* success, the second the load on failure.
|
||||
*/
|
||||
#define atomic_compare_exchange_strong(object, expected, desired) \
|
||||
__atomic_compare_exchange_n((object), (expected), (desired), 0, __ATOMIC_SEQ_CST, \
|
||||
__ATOMIC_SEQ_CST)
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
__atomic_compare_exchange_n((object), (expected), (desired), 0, (success), (failure))
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
__atomic_compare_exchange_n((object), (expected), (desired), 1, __ATOMIC_SEQ_CST, \
|
||||
__ATOMIC_SEQ_CST)
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
__atomic_compare_exchange_n((object), (expected), (desired), 1, (success), (failure))
|
||||
|
||||
/* Fetch and add; returns the previous value. */
|
||||
#define atomic_fetch_add(object, operand) __atomic_fetch_add((object), (operand), __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
__atomic_fetch_add((object), (operand), (order))
|
||||
|
||||
/* Fetch and subtract; returns the previous value. */
|
||||
#define atomic_fetch_sub(object, operand) __atomic_fetch_sub((object), (operand), __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
__atomic_fetch_sub((object), (operand), (order))
|
||||
|
||||
/* Fetch and bitwise-or; returns the previous value. */
|
||||
#define atomic_fetch_or(object, operand) __atomic_fetch_or((object), (operand), __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
__atomic_fetch_or((object), (operand), (order))
|
||||
|
||||
/* Fetch and bitwise-xor; returns the previous value. */
|
||||
#define atomic_fetch_xor(object, operand) __atomic_fetch_xor((object), (operand), __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
__atomic_fetch_xor((object), (operand), (order))
|
||||
|
||||
/* Fetch and bitwise-and; returns the previous value. */
|
||||
#define atomic_fetch_and(object, operand) __atomic_fetch_and((object), (operand), __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
__atomic_fetch_and((object), (operand), (order))
|
||||
|
||||
/* atomic_flag: test-and-set (returns the previous flag value). */
|
||||
#define atomic_flag_test_and_set(object) __atomic_test_and_set((object), __ATOMIC_SEQ_CST)
|
||||
#define atomic_flag_test_and_set_explicit(object, order) __atomic_test_and_set((object), (order))
|
||||
|
||||
/* atomic_flag: clear. */
|
||||
#define atomic_flag_clear(object) __atomic_clear((object), __ATOMIC_SEQ_CST)
|
||||
#define atomic_flag_clear_explicit(object, order) __atomic_clear((object), (order))
|
||||
|
||||
/* Non-zero iff *object is always lock-free. */
|
||||
#define atomic_is_lock_free(object) __atomic_is_lock_free(sizeof *(object), (object))
|
||||
|
||||
/* Fences. */
|
||||
#define atomic_thread_fence(order) __atomic_thread_fence((order))
|
||||
#define atomic_signal_fence(order) __atomic_signal_fence((order))
|
||||
|
||||
/* Carry a dependency through a load without a synchronization edge. */
|
||||
#define kill_dependency(y) (y)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VLIBC_STDATOMIC_H */
|
||||
Reference in New Issue
Block a user