blob: d3c9e960760709dd231355ba3994de96ace01bbb [file] [log] [blame] [edit]
/*
* Copyright 2019 The Emscripten Authors. All rights reserved.
* Emscripten is available under two separate licenses, the MIT license and the
* University of Illinois/NCSA Open Source License. Both these licenses can be
* found in the LICENSE file.
*/
#include <emscripten/threading.h>
uint8_t emscripten_atomic_exchange_u8(void /*uint8_t*/* addr, uint8_t newVal) {
return __c11_atomic_exchange((_Atomic uint8_t*)addr, newVal, __ATOMIC_SEQ_CST);
}
uint16_t emscripten_atomic_exchange_u16(void /*uint16_t*/* addr, uint16_t newVal) {
return __c11_atomic_exchange((_Atomic uint16_t*)addr, newVal, __ATOMIC_SEQ_CST);
}
uint32_t emscripten_atomic_exchange_u32(void /*uint32_t*/* addr, uint32_t newVal) {
return __c11_atomic_exchange((_Atomic uint32_t*)addr, newVal, __ATOMIC_SEQ_CST);
}
uint64_t emscripten_atomic_exchange_u64(void /*uint64_t*/* addr, uint64_t newVal) {
return __c11_atomic_exchange((_Atomic uint64_t*)addr, newVal, __ATOMIC_SEQ_CST);
}
uint8_t emscripten_atomic_cas_u8(void /*uint8_t*/* addr, uint8_t oldVal, uint8_t newVal) {
uint8_t expected = oldVal;
__c11_atomic_compare_exchange_strong(
(_Atomic uint8_t*)addr, &expected, newVal, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
uint16_t emscripten_atomic_cas_u16(void /*uint16_t*/* addr, uint16_t oldVal, uint16_t newVal) {
uint16_t expected = oldVal;
__c11_atomic_compare_exchange_strong(
(_Atomic uint16_t*)addr, &expected, newVal, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
uint32_t emscripten_atomic_cas_u32(void /*uint32_t*/* addr, uint32_t oldVal, uint32_t newVal) {
uint32_t expected = oldVal;
__c11_atomic_compare_exchange_strong(
(_Atomic uint32_t*)addr, &expected, newVal, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
uint64_t emscripten_atomic_cas_u64(void /*uint64_t*/* addr, uint64_t oldVal, uint64_t newVal) {
uint64_t expected = oldVal;
__c11_atomic_compare_exchange_strong(
(_Atomic uint64_t*)addr, &expected, newVal, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
uint8_t emscripten_atomic_load_u8(const void /*uint8_t*/* addr) {
return __c11_atomic_load((_Atomic(uint8_t)*)addr, __ATOMIC_SEQ_CST);
}
uint16_t emscripten_atomic_load_u16(const void /*uint16_t*/* addr) {
return __c11_atomic_load((_Atomic(uint16_t)*)addr, __ATOMIC_SEQ_CST);
}
uint32_t emscripten_atomic_load_u32(const void /*uint32_t*/* addr) {
return __c11_atomic_load((_Atomic(uint32_t)*)addr, __ATOMIC_SEQ_CST);
}
float emscripten_atomic_load_f32(const void /*float*/* addr) {
return __c11_atomic_load((_Atomic(float)*)addr, __ATOMIC_SEQ_CST);
}
uint64_t emscripten_atomic_load_u64(const void /*uint64_t*/* addr) {
return __c11_atomic_load((_Atomic(uint64_t)*)addr, __ATOMIC_SEQ_CST);
}
double emscripten_atomic_load_f64(const void /*double*/* addr) {
return __c11_atomic_load((_Atomic(double)*)addr, __ATOMIC_SEQ_CST);
}
// Returns the value that was stored (i.e. 'val')
uint8_t emscripten_atomic_store_u8(void /*uint8_t*/* addr, uint8_t val) {
__c11_atomic_store((_Atomic(uint8_t)*)addr, val, __ATOMIC_SEQ_CST);
return val;
}
uint16_t emscripten_atomic_store_u16(void /*uint16_t*/* addr, uint16_t val) {
__c11_atomic_store((_Atomic(uint16_t)*)addr, val, __ATOMIC_SEQ_CST);
return val;
}
uint32_t emscripten_atomic_store_u32(void /*uint32_t*/* addr, uint32_t val) {
__c11_atomic_store((_Atomic(uint32_t)*)addr, val, __ATOMIC_SEQ_CST);
return val;
}
float emscripten_atomic_store_f32(void /*float*/* addr, float val) {
__c11_atomic_store((_Atomic(float)*)addr, val, __ATOMIC_SEQ_CST);
return val;
}
uint64_t emscripten_atomic_store_u64(void /*uint64_t*/* addr, uint64_t val) {
__c11_atomic_store((_Atomic(uint64_t)*)addr, val, __ATOMIC_SEQ_CST);
return val;
}
double emscripten_atomic_store_f64(void /*double*/* addr, double val) {
__c11_atomic_store((_Atomic(double)*)addr, val, __ATOMIC_SEQ_CST);
return val;
}
void emscripten_atomic_fence(void) {
// Fake a fence with an arbitrary atomic operation
uint8_t temp = 0;
emscripten_atomic_or_u8(&temp, 0);
}
// Each of the functions below (add, sub, and, or, xor) return the value that was in the memory
// location before the operation occurred.
uint8_t emscripten_atomic_add_u8(void /*uint8_t*/* addr, uint8_t val) {
return __c11_atomic_fetch_add((_Atomic uint8_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint16_t emscripten_atomic_add_u16(void /*uint16_t*/* addr, uint16_t val) {
return __c11_atomic_fetch_add((_Atomic uint16_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint32_t emscripten_atomic_add_u32(void /*uint32_t*/* addr, uint32_t val) {
return __c11_atomic_fetch_add((_Atomic uint32_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint64_t emscripten_atomic_add_u64(void /*uint64_t*/* addr, uint64_t val) {
return __c11_atomic_fetch_add((_Atomic uint64_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint8_t emscripten_atomic_sub_u8(void /*uint8_t*/* addr, uint8_t val) {
return __c11_atomic_fetch_sub((_Atomic uint8_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint16_t emscripten_atomic_sub_u16(void /*uint16_t*/* addr, uint16_t val) {
return __c11_atomic_fetch_sub((_Atomic uint16_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint32_t emscripten_atomic_sub_u32(void /*uint32_t*/* addr, uint32_t val) {
return __c11_atomic_fetch_sub((_Atomic uint32_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint64_t emscripten_atomic_sub_u64(void /*uint64_t*/* addr, uint64_t val) {
return __c11_atomic_fetch_sub((_Atomic uint64_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint8_t emscripten_atomic_and_u8(void /*uint8_t*/* addr, uint8_t val) {
return __c11_atomic_fetch_and((_Atomic uint8_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint16_t emscripten_atomic_and_u16(void /*uint16_t*/* addr, uint16_t val) {
return __c11_atomic_fetch_and((_Atomic uint16_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint32_t emscripten_atomic_and_u32(void /*uint32_t*/* addr, uint32_t val) {
return __c11_atomic_fetch_and((_Atomic uint32_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint64_t emscripten_atomic_and_u64(void /*uint64_t*/* addr, uint64_t val) {
return __c11_atomic_fetch_and((_Atomic uint64_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint8_t emscripten_atomic_or_u8(void /*uint8_t*/* addr, uint8_t val) {
return __c11_atomic_fetch_or((_Atomic uint8_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint16_t emscripten_atomic_or_u16(void /*uint16_t*/* addr, uint16_t val) {
return __c11_atomic_fetch_or((_Atomic uint16_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint32_t emscripten_atomic_or_u32(void /*uint32_t*/* addr, uint32_t val) {
return __c11_atomic_fetch_or((_Atomic uint32_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint64_t emscripten_atomic_or_u64(void /*uint64_t*/* addr, uint64_t val) {
return __c11_atomic_fetch_or((_Atomic uint64_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint8_t emscripten_atomic_xor_u8(void /*uint8_t*/* addr, uint8_t val) {
return __c11_atomic_fetch_xor((_Atomic uint8_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint16_t emscripten_atomic_xor_u16(void /*uint16_t*/* addr, uint16_t val) {
return __c11_atomic_fetch_xor((_Atomic uint16_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint32_t emscripten_atomic_xor_u32(void /*uint32_t*/* addr, uint32_t val) {
return __c11_atomic_fetch_xor((_Atomic uint32_t*)addr, val, __ATOMIC_SEQ_CST);
}
uint64_t emscripten_atomic_xor_u64(void /*uint64_t*/* addr, uint64_t val) {
return __c11_atomic_fetch_xor((_Atomic uint64_t*)addr, val, __ATOMIC_SEQ_CST);
}