all repos — mgba @ b11de7538e29cc5777097ea8cedeb11db0983cf8

mGBA Game Boy Advance Emulator

Implement atomic macros for win32
Le Hoang Quyen lehoangq@gmail.com
Tue, 18 Dec 2018 02:58:35 +0800
commit

b11de7538e29cc5777097ea8cedeb11db0983cf8

parent

7a5840fb5a5a01ad94e886663d82079e42e1b001

2 files changed, 22 insertions(+), 8 deletions(-)

jump to
M include/mgba-util/common.hinclude/mgba-util/common.h

@@ -85,6 +85,18 @@ #define ATOMIC_SUB(DST, OP) __atomic_sub_fetch(&DST, OP, __ATOMIC_RELEASE)

#define ATOMIC_OR(DST, OP) __atomic_or_fetch(&DST, OP, __ATOMIC_RELEASE) #define ATOMIC_AND(DST, OP) __atomic_and_fetch(&DST, OP, __ATOMIC_RELEASE) #define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) __atomic_compare_exchange_n(&DST, &EXPECTED, SRC, true,__ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE) +#define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC) +#define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC) +#elif defined _MSC_VER +#define ATOMIC_STORE(DST, SRC) InterlockedExchange(&DST, SRC) +#define ATOMIC_LOAD(DST, SRC) DST = InterlockedOrAcquire(&SRC, 0) +#define ATOMIC_ADD(DST, OP) InterlockedAddRelease(&DST, OP) +#define ATOMIC_SUB(DST, OP) InterlockedAddRelease(&DST, -OP) +#define ATOMIC_OR(DST, OP) InterlockedOrRelease(&DST, OP) +#define ATOMIC_AND(DST, OP) InterlockedAndRelease(&DST, OP) +#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) (InterlockedCompareExchange(&DST, SRC, EXPECTED) == EXPECTED) +#define ATOMIC_STORE_PTR(DST, SRC) InterlockedExchangePointer(DST, SRC) +#define ATOMIC_LOAD_PTR(DST, SRC) DST = InterlockedCompareExchangePointer(SRC, 0, 0) #else // TODO #define ATOMIC_STORE(DST, SRC) DST = SRC

@@ -94,6 +106,8 @@ #define ATOMIC_SUB(DST, OP) DST -= OP

#define ATOMIC_OR(DST, OP) DST |= OP #define ATOMIC_AND(DST, OP) DST &= OP #define ATOMIC_CMPXCHG(DST, EXPECTED, OP) ((DST == EXPECTED) ? ((DST = OP), true) : false) +#define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC) +#define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC) #endif #if defined(_3DS) || defined(GEKKO) || defined(PSP2)
M src/util/ring-fifo.csrc/util/ring-fifo.c

@@ -25,8 +25,8 @@

size_t RingFIFOSize(const struct RingFIFO* buffer) { const void* read; const void* write; - ATOMIC_LOAD(read, buffer->readPtr); - ATOMIC_LOAD(write, buffer->writePtr); + ATOMIC_LOAD_PTR(read, buffer->readPtr); + ATOMIC_LOAD_PTR(write, buffer->writePtr); if (read <= write) { return (uintptr_t) write - (uintptr_t) read; } else {

@@ -35,14 +35,14 @@ }

} void RingFIFOClear(struct RingFIFO* buffer) { - ATOMIC_STORE(buffer->readPtr, buffer->data); - ATOMIC_STORE(buffer->writePtr, buffer->data); + ATOMIC_STORE_PTR(buffer->readPtr, buffer->data); + ATOMIC_STORE_PTR(buffer->writePtr, buffer->data); } size_t RingFIFOWrite(struct RingFIFO* buffer, const void* value, size_t length) { void* data = buffer->writePtr; void* end; - ATOMIC_LOAD(end, buffer->readPtr); + ATOMIC_LOAD_PTR(end, buffer->readPtr); // Wrap around if we can't fit enough in here if ((uintptr_t) data - (uintptr_t) buffer->data + length >= buffer->capacity) {

@@ -67,14 +67,14 @@ }

if (value) { memcpy(data, value, length); } - ATOMIC_STORE(buffer->writePtr, (void*) ((intptr_t) data + length)); + ATOMIC_STORE_PTR(buffer->writePtr, (void*) ((intptr_t) data + length)); return length; } size_t RingFIFORead(struct RingFIFO* buffer, void* output, size_t length) { void* data = buffer->readPtr; void* end; - ATOMIC_LOAD(end, buffer->writePtr); + ATOMIC_LOAD_PTR(end, buffer->writePtr); // Wrap around if we can't fit enough in here if ((uintptr_t) data - (uintptr_t) buffer->data + length >= buffer->capacity) {

@@ -99,6 +99,6 @@ }

if (output) { memcpy(output, data, length); } - ATOMIC_STORE(buffer->readPtr, (void*) ((uintptr_t) data + length)); + ATOMIC_STORE_PTR(buffer->readPtr, (void*) ((uintptr_t) data + length)); return length; }