1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 7 * 8 * See the COPYRIGHT file distributed with this work for additional 9 * information regarding copyright ownership. 10 */ 11 12 #pragma once 13 14 #include <inttypes.h> 15 #include <stdbool.h> 16 #include <stddef.h> 17 #if HAVE_UCHAR_H 18 #include <uchar.h> 19 #endif /* HAVE_UCHAR_H */ 20 21 /* GCC 4.7.0 introduced __atomic builtins, but not the __GNUC_ATOMICS define */ 22 #if !defined(__GNUC_ATOMICS) && __GNUC__ == 4 && __GNUC_MINOR__ >= 7 23 #define __GNUC_ATOMICS 24 #endif 25 26 #if !defined(__GNUC_ATOMICS) 27 #error "isc/stdatomic.h does not support your compiler" 28 #endif /* if !defined(__GNUC_ATOMICS) */ 29 30 #define ATOMIC_VAR_INIT(x) x 31 32 typedef enum memory_order { 33 memory_order_relaxed = __ATOMIC_RELAXED, 34 memory_order_consume = __ATOMIC_CONSUME, 35 memory_order_acquire = __ATOMIC_ACQUIRE, 36 memory_order_release = __ATOMIC_RELEASE, 37 memory_order_acq_rel = __ATOMIC_ACQ_REL, 38 memory_order_seq_cst = __ATOMIC_SEQ_CST 39 } memory_order; 40 41 #ifndef HAVE_UCHAR_H 42 typedef uint_least16_t char16_t; 43 typedef uint_least32_t char32_t; 44 #endif /* HAVE_UCHAR_H */ 45 46 typedef bool atomic_bool; 47 typedef char atomic_char; 48 typedef signed char atomic_schar; 49 typedef unsigned char atomic_uchar; 50 typedef short atomic_short; 51 typedef unsigned short atomic_ushort; 52 typedef int atomic_int; 53 typedef unsigned int atomic_uint; 54 typedef long atomic_long; 55 typedef unsigned long atomic_ulong; 56 typedef long long atomic_llong; 57 typedef unsigned long long atomic_ullong; 58 typedef char16_t atomic_char16_t; 59 typedef char32_t atomic_char32_t; 60 typedef wchar_t atomic_wchar_t; 61 typedef int_least8_t atomic_int_least8_t; 62 typedef uint_least8_t atomic_uint_least8_t; 63 typedef int_least16_t atomic_int_least16_t; 64 typedef uint_least16_t atomic_uint_least16_t; 65 typedef int_least32_t atomic_int_least32_t; 66 typedef uint_least32_t atomic_uint_least32_t; 67 typedef int_least64_t atomic_int_least64_t; 68 typedef uint_least64_t atomic_uint_least64_t; 69 typedef int_fast8_t atomic_int_fast8_t; 70 typedef uint_fast8_t atomic_uint_fast8_t; 71 typedef int_fast16_t atomic_int_fast16_t; 72 typedef uint_fast16_t atomic_uint_fast16_t; 73 typedef int_fast32_t atomic_int_fast32_t; 74 typedef uint_fast32_t atomic_uint_fast32_t; 75 typedef int_fast64_t atomic_int_fast64_t; 76 typedef uint_fast64_t atomic_uint_fast64_t; 77 typedef intptr_t atomic_intptr_t; 78 typedef uintptr_t atomic_uintptr_t; 79 typedef size_t atomic_size_t; 80 typedef ptrdiff_t atomic_ptrdiff_t; 81 typedef intmax_t atomic_intmax_t; 82 typedef uintmax_t atomic_uintmax_t; 83 84 #define atomic_init(obj, desired) (*obj = desired) 85 #define atomic_load_explicit(obj, order) __atomic_load_n(obj, order) 86 #define atomic_store_explicit(obj, desired, order) \ 87 __atomic_store_n(obj, desired, order) 88 #define atomic_fetch_add_explicit(obj, arg, order) \ 89 __atomic_fetch_add(obj, arg, order) 90 #define atomic_fetch_sub_explicit(obj, arg, order) \ 91 __atomic_fetch_sub(obj, arg, order) 92 #define atomic_fetch_and_explicit(obj, arg, order) \ 93 __atomic_fetch_and(obj, arg, order) 94 #define atomic_fetch_or_explicit(obj, arg, order) \ 95 __atomic_fetch_or(obj, arg, order) 96 #define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ 97 fail) \ 98 __atomic_compare_exchange_n(obj, expected, desired, 0, succ, fail) 99 #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ 100 fail) \ 101 __atomic_compare_exchange_n(obj, expected, desired, 1, succ, fail) 102 #define atomic_exchange_explicit(obj, desired, order) \ 103 __atomic_exchange_n(obj, desired, order) 104 105 #define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst) 106 #define atomic_store(obj, arg) \ 107 atomic_store_explicit(obj, arg, memory_order_seq_cst) 108 #define atomic_fetch_add(obj, arg) \ 109 atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst) 110 #define atomic_fetch_sub(obj, arg) \ 111 atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst) 112 #define atomic_fetch_and(obj, arg) \ 113 atomic_fetch_and_explicit(obj, arg, memory_order_seq_cst) 114 #define atomic_fetch_or(obj, arg) \ 115 atomic_fetch_or_explicit(obj, arg, memory_order_seq_cst) 116 #define atomic_compare_exchange_strong(obj, expected, desired) \ 117 atomic_compare_exchange_strong_explicit(obj, expected, desired, \ 118 memory_order_seq_cst, \ 119 memory_order_seq_cst) 120 #define atomic_compare_exchange_weak(obj, expected, desired) \ 121 atomic_compare_exchange_weak_explicit(obj, expected, desired, \ 122 memory_order_seq_cst, \ 123 memory_order_seq_cst) 124 #define atomic_exchange(obj, desired) \ 125 atomic_exchange_explicit(obj, desired, memory_order_seq_cst) 126