1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
#ifndef AWS_COMMON_ATOMICS_INL
#define AWS_COMMON_ATOMICS_INL
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/common/atomics.h>
#include <aws/common/common.h>
AWS_EXTERN_C_BEGIN
/**
* Reads an atomic var as an integer, using sequentially consistent ordering, and returns the result.
*/
AWS_STATIC_IMPL
size_t aws_atomic_load_int(volatile const struct aws_atomic_var *var) {
return aws_atomic_load_int_explicit(var, aws_memory_order_seq_cst);
}
/**
* Reads an atomic var as a pointer, using sequentially consistent ordering, and returns the result.
*/
AWS_STATIC_IMPL
void *aws_atomic_load_ptr(volatile const struct aws_atomic_var *var) {
return aws_atomic_load_ptr_explicit(var, aws_memory_order_seq_cst);
}
/**
* Stores an integer into an atomic var, using sequentially consistent ordering.
*/
AWS_STATIC_IMPL
void aws_atomic_store_int(volatile struct aws_atomic_var *var, size_t n) {
aws_atomic_store_int_explicit(var, n, aws_memory_order_seq_cst);
}
/**
* Stores a pointer into an atomic var, using sequentially consistent ordering.
*/
AWS_STATIC_IMPL
void aws_atomic_store_ptr(volatile struct aws_atomic_var *var, void *p) {
aws_atomic_store_ptr_explicit(var, p, aws_memory_order_seq_cst);
}
/**
* Exchanges an integer with the value in an atomic_var, using sequentially consistent ordering.
* Returns the value that was previously in the atomic_var.
*/
AWS_STATIC_IMPL
size_t aws_atomic_exchange_int(volatile struct aws_atomic_var *var, size_t n) {
return aws_atomic_exchange_int_explicit(var, n, aws_memory_order_seq_cst);
}
/**
* Exchanges an integer with the value in an atomic_var, using sequentially consistent ordering.
* Returns the value that was previously in the atomic_var.
*/
AWS_STATIC_IMPL
void *aws_atomic_exchange_ptr(volatile struct aws_atomic_var *var, void *p) {
return aws_atomic_exchange_ptr_explicit(var, p, aws_memory_order_seq_cst);
}
/**
* Atomically compares *var to *expected; if they are equal, atomically sets *var = desired. Otherwise, *expected is set
* to the value in *var. Uses sequentially consistent memory ordering, regardless of success or failure.
* Returns true if the compare was successful and the variable updated to desired.
*/
AWS_STATIC_IMPL
bool aws_atomic_compare_exchange_int(volatile struct aws_atomic_var *var, size_t *expected, size_t desired) {
return aws_atomic_compare_exchange_int_explicit(
var, expected, desired, aws_memory_order_seq_cst, aws_memory_order_seq_cst);
}
/**
* Atomically compares *var to *expected; if they are equal, atomically sets *var = desired. Otherwise, *expected is set
* to the value in *var. Uses sequentially consistent memory ordering, regardless of success or failure.
* Returns true if the compare was successful and the variable updated to desired.
*/
AWS_STATIC_IMPL
bool aws_atomic_compare_exchange_ptr(volatile struct aws_atomic_var *var, void **expected, void *desired) {
return aws_atomic_compare_exchange_ptr_explicit(
var, expected, desired, aws_memory_order_seq_cst, aws_memory_order_seq_cst);
}
/**
* Atomically adds n to *var, and returns the previous value of *var.
* Uses sequentially consistent ordering.
*/
AWS_STATIC_IMPL
size_t aws_atomic_fetch_add(volatile struct aws_atomic_var *var, size_t n) {
return aws_atomic_fetch_add_explicit(var, n, aws_memory_order_seq_cst);
}
/**
* Atomically subtracts n from *var, and returns the previous value of *var.
* Uses sequentially consistent ordering.
*/
AWS_STATIC_IMPL
size_t aws_atomic_fetch_sub(volatile struct aws_atomic_var *var, size_t n) {
return aws_atomic_fetch_sub_explicit(var, n, aws_memory_order_seq_cst);
}
/**
* Atomically ands n into *var, and returns the previous value of *var.
* Uses sequentially consistent ordering.
*/
AWS_STATIC_IMPL
size_t aws_atomic_fetch_and(volatile struct aws_atomic_var *var, size_t n) {
return aws_atomic_fetch_and_explicit(var, n, aws_memory_order_seq_cst);
}
/**
* Atomically ors n into *var, and returns the previous value of *var.
* Uses sequentially consistent ordering.
*/
AWS_STATIC_IMPL
size_t aws_atomic_fetch_or(volatile struct aws_atomic_var *var, size_t n) {
return aws_atomic_fetch_or_explicit(var, n, aws_memory_order_seq_cst);
}
/**
* Atomically xors n into *var, and returns the previous value of *var.
* Uses sequentially consistent ordering.
*/
AWS_STATIC_IMPL
size_t aws_atomic_fetch_xor(volatile struct aws_atomic_var *var, size_t n) {
return aws_atomic_fetch_xor_explicit(var, n, aws_memory_order_seq_cst);
}
/* Include the backend implementation now, because we'll use its typedefs and #defines below */
#if defined(__GNUC__) || defined(__clang__)
# if defined(__ATOMIC_RELAXED)
# include <aws/common/atomics_gnu.inl>
# else
# include <aws/common/atomics_gnu_old.inl>
# endif /* __ATOMIC_RELAXED */
#elif defined(_MSC_VER)
# include <aws/common/atomics_msvc.inl>
#else
# error No atomics implementation for your compiler is available
#endif
#include <aws/common/atomics_fallback.inl>
AWS_EXTERN_C_END
#endif /* AWS_COMMON_ATOMICS_INL */
|