Implement atomic macros for win32

This commit is contained in:
Le Hoang Quyen 2018-12-18 02:58:35 +08:00 committed by Vicki Pfau
parent 7a5840fb5a
commit b11de7538e
2 changed files with 22 additions and 8 deletions

View File

@ -85,6 +85,18 @@ typedef intptr_t ssize_t;
#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 @@ typedef intptr_t ssize_t;
#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)

View File

@ -25,8 +25,8 @@ size_t RingFIFOCapacity(const struct RingFIFO* buffer) {
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 @@ size_t RingFIFOSize(const struct RingFIFO* buffer) {
}
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 @@ size_t RingFIFOWrite(struct RingFIFO* buffer, const void* value, size_t length)
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 @@ size_t RingFIFORead(struct RingFIFO* buffer, void* output, size_t length) {
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;
}