Implement atomic macros for win32
Le Hoang Quyen lehoangq@gmail.com
Tue, 18 Dec 2018 02:58:35 +0800
2 files changed,
22 insertions(+),
8 deletions(-)
M
include/mgba-util/common.h
→
include/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.c
→
src/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; }