зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1701879 part 5 - Add stub atomics implementation for WASI. r=wingo,glandium
WASI lacks of the <atomic> support yet, so this patch is adding stub implementation of atomics for WASI. Differential Revision: https://phabricator.services.mozilla.com/D110215
This commit is contained in:
Родитель
7258cd0454
Коммит
3cc53df2c0
|
@ -382,7 +382,7 @@ constexpr inline bool AtomicOperations::isLockfreeJS(int32_t size) {
|
|||
defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || \
|
||||
defined(__PPC64LE__) || defined(__alpha__) || defined(__hppa__) || \
|
||||
defined(__sh__) || defined(__s390__) || defined(__s390x__) || \
|
||||
defined(__m68k__) || defined(__riscv)
|
||||
defined(__m68k__) || defined(__riscv) || defined(__wasi__)
|
||||
# include "jit/shared/AtomicOperations-feeling-lucky.h"
|
||||
#else
|
||||
# error "No AtomicOperations support provided for this platform"
|
||||
|
|
|
@ -11,11 +11,16 @@
|
|||
#include "mozilla/MacroArgs.h"
|
||||
#include "mozilla/MacroForEach.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef __wasi__
|
||||
# include "mozilla/WasiAtomic.h"
|
||||
#else
|
||||
# include <atomic>
|
||||
#endif // __wasi__
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Creates a series of atomic bitfields.
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Compiler.h"
|
||||
|
||||
#include <atomic>
|
||||
#ifdef __wasi__
|
||||
# include "mozilla/WasiAtomic.h"
|
||||
#else
|
||||
# include <atomic>
|
||||
#endif // __wasi__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <type_traits>
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_WasiAtomic_h
|
||||
#define mozilla_WasiAtomic_h
|
||||
|
||||
// WASI doesn't support <atomic> and we use it as single-threaded for now.
|
||||
// This is a stub implementation of std atomics to build WASI port of SM.
|
||||
|
||||
namespace std {
|
||||
enum memory_order {
|
||||
relaxed,
|
||||
consume, // load-consume
|
||||
acquire, // load-acquire
|
||||
release, // store-release
|
||||
acq_rel, // store-release load-acquire
|
||||
seq_cst // store-release load-acquire
|
||||
};
|
||||
|
||||
inline constexpr auto memory_order_relaxed = memory_order::relaxed;
|
||||
inline constexpr auto memory_order_consume = memory_order::consume;
|
||||
inline constexpr auto memory_order_acquire = memory_order::acquire;
|
||||
inline constexpr auto memory_order_release = memory_order::release;
|
||||
inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
|
||||
inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
|
||||
|
||||
template <class T>
|
||||
struct atomic {
|
||||
using value_type = T;
|
||||
value_type value_;
|
||||
|
||||
atomic() noexcept = default;
|
||||
constexpr atomic(T desired) noexcept : value_{desired} {}
|
||||
|
||||
atomic(const atomic&) = delete;
|
||||
atomic& operator=(const atomic&) = delete;
|
||||
atomic& operator=(const atomic&) volatile = delete;
|
||||
~atomic() noexcept = default;
|
||||
|
||||
T load(memory_order) const volatile noexcept { return value_; }
|
||||
|
||||
void store(T desired,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
value_ = desired;
|
||||
}
|
||||
|
||||
T operator=(T desired) volatile noexcept { return value_ = desired; }
|
||||
|
||||
T exchange(T desired,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T tmp = value_;
|
||||
value_ = desired;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool compare_exchange_weak(T& expected, T desired, memory_order,
|
||||
memory_order) volatile noexcept {
|
||||
expected = desired;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compare_exchange_weak(
|
||||
T& expected, T desired,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
expected = desired;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compare_exchange_strong(T& expected, T desired, memory_order,
|
||||
memory_order) volatile noexcept {
|
||||
expected = desired;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compare_exchange_strong(
|
||||
T& expected, T desired,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
expected = desired;
|
||||
return true;
|
||||
}
|
||||
|
||||
T fetch_add(T arg, memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T previous = value_;
|
||||
value_ = value_ + arg;
|
||||
return previous;
|
||||
}
|
||||
|
||||
T fetch_sub(T arg, memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T previous = value_;
|
||||
value_ = value_ - arg;
|
||||
return previous;
|
||||
}
|
||||
|
||||
T fetch_or(T arg, memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T previous = value_;
|
||||
value_ = value_ | arg;
|
||||
return previous;
|
||||
}
|
||||
|
||||
T fetch_xor(T arg, memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T previous = value_;
|
||||
value_ = value_ ^ arg;
|
||||
return previous;
|
||||
}
|
||||
|
||||
T fetch_and(T arg, memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T previous = value_;
|
||||
value_ = value_ & arg;
|
||||
return previous;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct atomic<T*> {
|
||||
using value_type = T*;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
value_type value_;
|
||||
|
||||
atomic() noexcept = default;
|
||||
constexpr atomic(T* desired) noexcept : value_{desired} {}
|
||||
atomic(const atomic&) = delete;
|
||||
atomic& operator=(const atomic&) = delete;
|
||||
atomic& operator=(const atomic&) volatile = delete;
|
||||
|
||||
T* load(memory_order m = memory_order_seq_cst) const volatile noexcept {
|
||||
return value_;
|
||||
}
|
||||
|
||||
void store(T* desired,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
value_ = desired;
|
||||
}
|
||||
|
||||
T* operator=(T* other) volatile noexcept { return value_ = other; }
|
||||
|
||||
T* exchange(T* desired,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T* previous = value_;
|
||||
value_ = desired;
|
||||
return previous;
|
||||
}
|
||||
|
||||
bool compare_exchange_weak(T*& expected, T* desired, memory_order s,
|
||||
memory_order f) volatile noexcept {
|
||||
expected = desired;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compare_exchange_weak(
|
||||
T*& expected, T* desired,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
expected = desired;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compare_exchange_strong(T*& expected, T* desired, memory_order s,
|
||||
memory_order f) volatile noexcept {
|
||||
expected = desired;
|
||||
return true;
|
||||
}
|
||||
|
||||
T* fetch_add(ptrdiff_t arg,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T* previous = value_;
|
||||
value_ = value_ + arg;
|
||||
return previous;
|
||||
}
|
||||
|
||||
T* fetch_sub(ptrdiff_t arg,
|
||||
memory_order m = memory_order_seq_cst) volatile noexcept {
|
||||
T* previous = value_;
|
||||
value_ = value_ - arg;
|
||||
return previous;
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif // mozilla_WasiAtomic_h
|
|
@ -140,6 +140,11 @@ if CONFIG["OS_ARCH"] == "WINNT":
|
|||
"WindowsVersion.h",
|
||||
]
|
||||
|
||||
if CONFIG["OS_ARCH"] == "WASI":
|
||||
EXPORTS.mozilla += [
|
||||
"WasiAtomic.h",
|
||||
]
|
||||
|
||||
if CONFIG["MOZ_TSAN"]:
|
||||
EXPORTS.mozilla += [
|
||||
"TsanOptions.h",
|
||||
|
|
Загрузка…
Ссылка в новой задаче