1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/*
* 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);
}
|