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