1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_WasiAtomic_h
8 #define mozilla_WasiAtomic_h
10 // Clang >= 14 supports <atomic> for wasm targets.
11 #if _LIBCPP_VERSION >= 14000
17 // WASI doesn't support <atomic> and we use it as single-threaded for now.
18 // This is a stub implementation of std atomics to build WASI port of SM.
23 consume
, // load-consume
24 acquire
, // load-acquire
25 release
, // store-release
26 acq_rel
, // store-release load-acquire
27 seq_cst
// store-release load-acquire
30 inline constexpr auto memory_order_relaxed
= memory_order::relaxed
;
31 inline constexpr auto memory_order_consume
= memory_order::consume
;
32 inline constexpr auto memory_order_acquire
= memory_order::acquire
;
33 inline constexpr auto memory_order_release
= memory_order::release
;
34 inline constexpr auto memory_order_acq_rel
= memory_order::acq_rel
;
35 inline constexpr auto memory_order_seq_cst
= memory_order::seq_cst
;
42 atomic() noexcept
= default;
43 constexpr atomic(T desired
) noexcept
: value_
{desired
} {}
45 atomic(const atomic
&) = delete;
46 atomic
& operator=(const atomic
&) = delete;
47 atomic
& operator=(const atomic
&) volatile = delete;
48 ~atomic() noexcept
= default;
50 T
load(memory_order m
= memory_order_seq_cst
) const volatile noexcept
{
55 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
59 T
operator=(T desired
) volatile noexcept
{ return value_
= desired
; }
62 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
68 bool compare_exchange_weak(T
& expected
, T desired
, memory_order
,
69 memory_order
) volatile noexcept
{
74 bool compare_exchange_weak(
75 T
& expected
, T desired
,
76 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
81 bool compare_exchange_strong(T
& expected
, T desired
, memory_order
,
82 memory_order
) volatile noexcept
{
87 bool compare_exchange_strong(
88 T
& expected
, T desired
,
89 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
94 T
fetch_add(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
96 value_
= value_
+ arg
;
100 T
fetch_sub(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
102 value_
= value_
- arg
;
106 T
fetch_or(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
108 value_
= value_
| arg
;
112 T
fetch_xor(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
114 value_
= value_
^ arg
;
118 T
fetch_and(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
120 value_
= value_
& arg
;
127 using value_type
= T
*;
128 using difference_type
= ptrdiff_t;
132 atomic() noexcept
= default;
133 constexpr atomic(T
* desired
) noexcept
: value_
{desired
} {}
134 atomic(const atomic
&) = delete;
135 atomic
& operator=(const atomic
&) = delete;
136 atomic
& operator=(const atomic
&) volatile = delete;
138 T
* load(memory_order m
= memory_order_seq_cst
) const volatile noexcept
{
142 void store(T
* desired
,
143 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
147 T
* operator=(T
* other
) volatile noexcept
{ return value_
= other
; }
149 T
* exchange(T
* desired
,
150 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
151 T
* previous
= value_
;
156 bool compare_exchange_weak(T
*& expected
, T
* desired
, memory_order s
,
157 memory_order f
) volatile noexcept
{
162 bool compare_exchange_weak(
163 T
*& expected
, T
* desired
,
164 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
169 bool compare_exchange_strong(T
*& expected
, T
* desired
, memory_order s
,
170 memory_order f
) volatile noexcept
{
175 T
* fetch_add(ptrdiff_t arg
,
176 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
177 T
* previous
= value_
;
178 value_
= value_
+ arg
;
182 T
* fetch_sub(ptrdiff_t arg
,
183 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
184 T
* previous
= value_
;
185 value_
= value_
- arg
;
190 using atomic_uint8_t
= atomic
<uint8_t>;
191 using atomic_uint16_t
= atomic
<uint16_t>;
192 using atomic_uint32_t
= atomic
<uint32_t>;
193 using atomic_uint64_t
= atomic
<uint64_t>;
199 #endif // mozilla_WasiAtomic_h