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
12 // WASI doesn't support <atomic> and we use it as single-threaded for now.
13 // This is a stub implementation of std atomics to build WASI port of SM.
18 consume
, // load-consume
19 acquire
, // load-acquire
20 release
, // store-release
21 acq_rel
, // store-release load-acquire
22 seq_cst
// store-release load-acquire
25 inline constexpr auto memory_order_relaxed
= memory_order::relaxed
;
26 inline constexpr auto memory_order_consume
= memory_order::consume
;
27 inline constexpr auto memory_order_acquire
= memory_order::acquire
;
28 inline constexpr auto memory_order_release
= memory_order::release
;
29 inline constexpr auto memory_order_acq_rel
= memory_order::acq_rel
;
30 inline constexpr auto memory_order_seq_cst
= memory_order::seq_cst
;
37 atomic() noexcept
= default;
38 constexpr atomic(T desired
) noexcept
: value_
{desired
} {}
40 atomic(const atomic
&) = delete;
41 atomic
& operator=(const atomic
&) = delete;
42 atomic
& operator=(const atomic
&) volatile = delete;
43 ~atomic() noexcept
= default;
45 T
load(memory_order m
= memory_order_seq_cst
) const volatile noexcept
{
50 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
54 T
operator=(T desired
) volatile noexcept
{ return value_
= desired
; }
57 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
63 bool compare_exchange_weak(T
& expected
, T desired
, memory_order
,
64 memory_order
) volatile noexcept
{
69 bool compare_exchange_weak(
70 T
& expected
, T desired
,
71 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
76 bool compare_exchange_strong(T
& expected
, T desired
, memory_order
,
77 memory_order
) volatile noexcept
{
82 bool compare_exchange_strong(
83 T
& expected
, T desired
,
84 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
89 T
fetch_add(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
91 value_
= value_
+ arg
;
95 T
fetch_sub(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
97 value_
= value_
- arg
;
101 T
fetch_or(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
103 value_
= value_
| arg
;
107 T
fetch_xor(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
109 value_
= value_
^ arg
;
113 T
fetch_and(T arg
, memory_order m
= memory_order_seq_cst
) volatile noexcept
{
115 value_
= value_
& arg
;
122 using value_type
= T
*;
123 using difference_type
= ptrdiff_t;
127 atomic() noexcept
= default;
128 constexpr atomic(T
* desired
) noexcept
: value_
{desired
} {}
129 atomic(const atomic
&) = delete;
130 atomic
& operator=(const atomic
&) = delete;
131 atomic
& operator=(const atomic
&) volatile = delete;
133 T
* load(memory_order m
= memory_order_seq_cst
) const volatile noexcept
{
137 void store(T
* desired
,
138 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
142 T
* operator=(T
* other
) volatile noexcept
{ return value_
= other
; }
144 T
* exchange(T
* desired
,
145 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
146 T
* previous
= value_
;
151 bool compare_exchange_weak(T
*& expected
, T
* desired
, memory_order s
,
152 memory_order f
) volatile noexcept
{
157 bool compare_exchange_weak(
158 T
*& expected
, T
* desired
,
159 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
164 bool compare_exchange_strong(T
*& expected
, T
* desired
, memory_order s
,
165 memory_order f
) volatile noexcept
{
170 T
* fetch_add(ptrdiff_t arg
,
171 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
172 T
* previous
= value_
;
173 value_
= value_
+ arg
;
177 T
* fetch_sub(ptrdiff_t arg
,
178 memory_order m
= memory_order_seq_cst
) volatile noexcept
{
179 T
* previous
= value_
;
180 value_
= value_
- arg
;
185 using atomic_uint8_t
= atomic
<uint8_t>;
186 using atomic_uint16_t
= atomic
<uint16_t>;
187 using atomic_uint32_t
= atomic
<uint32_t>;
188 using atomic_uint64_t
= atomic
<uint64_t>;
192 #endif // mozilla_WasiAtomic_h