mirror of https://github.com/mgba-emu/mgba.git
Implement atomic macros for win32
This commit is contained in:
parent
7a5840fb5a
commit
b11de7538e
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue