From 8f581c0e66e52a6f24e85763b39ed3be29a3e792 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 20 Dec 2016 20:49:37 -0800 Subject: [PATCH] Use separate macros for atomics that don't take a memory order --- Alc/ALc.c | 70 +++++++++++++++++----------------- Alc/ALu.c | 14 +++---- Alc/helpers.c | 8 ++-- Alc/mixer.c | 4 +- OpenAL32/alAuxEffectSlot.c | 22 +++++------ OpenAL32/alBuffer.c | 18 ++++----- OpenAL32/alError.c | 4 +- OpenAL32/alListener.c | 4 +- OpenAL32/alSource.c | 61 +++++++++++++++-------------- OpenAL32/alThunk.c | 8 ++-- include/atomic.h | 95 ++++++++++++++++++++++++---------------------- 11 files changed, 159 insertions(+), 149 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index 2e7c1e7f..95d5e178 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1173,7 +1173,7 @@ static void alc_cleanup(void) free(alcCaptureDefaultDeviceSpecifier); alcCaptureDefaultDeviceSpecifier = NULL; - if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL) + if((dev=ATOMIC_EXCHANGE_SEQ(ALCdevice*, &DeviceList, NULL)) != NULL) { ALCuint num = 0; do { @@ -1587,7 +1587,7 @@ extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS */ void ALCcontext_DeferUpdates(ALCcontext *context, ALenum type) { - ATOMIC_STORE(&context->DeferUpdates, type); + ATOMIC_STORE_SEQ(&context->DeferUpdates, type); } /* ALCcontext_ProcessUpdates @@ -1599,7 +1599,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) ALCdevice *device = context->Device; ReadLock(&context->PropLock); - if(ATOMIC_EXCHANGE(ALenum, &context->DeferUpdates, AL_FALSE)) + if(ATOMIC_EXCHANGE_SEQ(ALenum, &context->DeferUpdates, AL_FALSE)) { ALsizei pos; uint updates; @@ -1607,7 +1607,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) /* Tell the mixer to stop applying updates, then wait for any active * updating to finish, before providing updates. */ - ATOMIC_STORE(&context->HoldUpdates, AL_TRUE); + ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE); while(((updates=ReadRef(&context->UpdateCount))&1) != 0) althrd_yield(); @@ -1642,7 +1642,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) /* Now with all updates declared, let the mixer continue applying them * so they all happen at once. */ - ATOMIC_STORE(&context->HoldUpdates, AL_FALSE); + ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE); } ReadUnlock(&context->PropLock); } @@ -1666,9 +1666,9 @@ static void alcSetError(ALCdevice *device, ALCenum errorCode) } if(device) - ATOMIC_STORE(&device->LastError, errorCode); + ATOMIC_STORE_SEQ(&device->LastError, errorCode); else - ATOMIC_STORE(&LastNullDeviceError, errorCode); + ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode); } @@ -2098,7 +2098,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) UpdateEffectSlotProps(slot); } - context = ATOMIC_LOAD(&device->ContextList); + context = ATOMIC_LOAD_SEQ(&device->ContextList); while(context) { ALsizei pos; @@ -2260,7 +2260,7 @@ static ALCboolean VerifyDevice(ALCdevice **device) ALCdevice *tmpDevice; LockLists(); - tmpDevice = ATOMIC_LOAD(&DeviceList); + tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList); while(tmpDevice) { if(tmpDevice == *device) @@ -2413,12 +2413,13 @@ static void ReleaseContext(ALCcontext *context, ALCdevice *device) } origctx = context; - if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL)) + if(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &GlobalContext, &origctx, NULL)) ALCcontext_DecRef(context); ALCdevice_Lock(device); origctx = context; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, context->next)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &device->ContextList, + &origctx, context->next)) { ALCcontext *volatile*list = &origctx->next; while(*list) @@ -2466,10 +2467,10 @@ static ALCboolean VerifyContext(ALCcontext **context) ALCdevice *dev; LockLists(); - dev = ATOMIC_LOAD(&DeviceList); + dev = ATOMIC_LOAD_SEQ(&DeviceList); while(dev) { - ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList); + ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire); while(ctx) { if(ctx == *context) @@ -2504,7 +2505,7 @@ ALCcontext *GetContextRef(void) else { LockLists(); - context = ATOMIC_LOAD(&GlobalContext); + context = ATOMIC_LOAD_SEQ(&GlobalContext); if(context) ALCcontext_IncRef(context); UnlockLists(); @@ -2528,11 +2529,11 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) if(VerifyDevice(&device)) { - errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &device->LastError, ALC_NO_ERROR); ALCdevice_DecRef(device); } else - errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &LastNullDeviceError, ALC_NO_ERROR); return errorCode; } @@ -3178,7 +3179,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin almtx_lock(&device->BackendLock); UnlockLists(); - ATOMIC_STORE(&device->LastError, ALC_NO_ERROR); + ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR); ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener)); if(ALContext) @@ -3251,10 +3252,11 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin UpdateListenerProps(ALContext); { - ALCcontext *head = ATOMIC_LOAD(&device->ContextList); + ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList); do { ALContext->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext)); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCcontext*, + &device->ContextList, &head, ALContext) == 0); } almtx_unlock(&device->BackendLock); @@ -3279,7 +3281,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) { almtx_lock(&Device->BackendLock); ReleaseContext(context, Device); - if(!ATOMIC_LOAD(&Device->ContextList)) + if(!ATOMIC_LOAD_SEQ(&Device->ContextList)) { V0(Device->Backend,stop)(); Device->Flags &= ~DEVICE_RUNNING; @@ -3297,7 +3299,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) { ALCcontext *Context = altss_get(LocalContext); - if(!Context) Context = ATOMIC_LOAD(&GlobalContext); + if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext); return Context; } @@ -3325,7 +3327,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) return ALC_FALSE; } /* context's reference count is already incremented */ - context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context); + context = ATOMIC_EXCHANGE_SEQ(ALCcontext*, &GlobalContext, context); if(context) ALCcontext_DecRef(context); if((context=altss_get(LocalContext)) != NULL) @@ -3606,10 +3608,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) } { - ALCdevice *head = ATOMIC_LOAD(&DeviceList); + ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); } TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName)); @@ -3626,7 +3628,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) ALCcontext *ctx; LockLists(); - iter = ATOMIC_LOAD(&DeviceList); + iter = ATOMIC_LOAD_SEQ(&DeviceList); do { if(iter == device) break; @@ -3640,7 +3642,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) almtx_lock(&device->BackendLock); origdev = device; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, device->next)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next)) { ALCdevice *volatile*list = &origdev->next; while(*list) @@ -3655,7 +3657,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) } UnlockLists(); - ctx = ATOMIC_LOAD(&device->ContextList); + ctx = ATOMIC_LOAD_SEQ(&device->ContextList); while(ctx != NULL) { ALCcontext *next = ctx->next; @@ -3766,10 +3768,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, almtx_init(&device->BackendLock, almtx_plain); { - ALCdevice *head = ATOMIC_LOAD(&DeviceList); + ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); } TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName)); @@ -3781,7 +3783,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) ALCdevice *iter, *origdev; LockLists(); - iter = ATOMIC_LOAD(&DeviceList); + iter = ATOMIC_LOAD_SEQ(&DeviceList); do { if(iter == device) break; @@ -3794,7 +3796,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) } origdev = device; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, device->next)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next)) { ALCdevice *volatile*list = &origdev->next; while(*list) @@ -3973,10 +3975,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN V(device->Backend,open)("Loopback"); { - ALCdevice *head = ATOMIC_LOAD(&DeviceList); + ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); } TRACE("Created device %p\n", device); @@ -4062,7 +4064,7 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) if((device->Flags&DEVICE_PAUSED)) { device->Flags &= ~DEVICE_PAUSED; - if(ATOMIC_LOAD(&device->ContextList) != NULL) + if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL) { if(V0(device->Backend,start)() != ALC_FALSE) device->Flags |= DEVICE_RUNNING; diff --git a/Alc/ALu.c b/Alc/ALu.c index b90a3983..db032057 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1347,7 +1347,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) ALsource *source; IncrementRef(&ctx->UpdateCount); - if(!ATOMIC_LOAD(&ctx->HoldUpdates)) + if(!ATOMIC_LOAD(&ctx->HoldUpdates, almemory_order_acquire)) { ALboolean force = CalcListenerParams(ctx); while(slot) @@ -1461,12 +1461,12 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) memset(slot->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); } - ctx = ATOMIC_LOAD(&device->ContextList); + ctx = ATOMIC_LOAD(&device->ContextList, almemory_order_acquire); while(ctx) { ALeffectslot *slotroot; - slotroot = ATOMIC_LOAD(&ctx->ActiveAuxSlotList); + slotroot = ATOMIC_LOAD(&ctx->ActiveAuxSlotList, almemory_order_acquire); UpdateContextSources(ctx, slotroot); slot = slotroot; @@ -1631,7 +1631,7 @@ ALvoid aluHandleDisconnect(ALCdevice *device) device->Connected = ALC_FALSE; - Context = ATOMIC_LOAD(&device->ContextList); + Context = ATOMIC_LOAD_SEQ(&device->ContextList); while(Context) { ALvoice *voice, *voice_end; @@ -1646,9 +1646,9 @@ ALvoid aluHandleDisconnect(ALCdevice *device) if(source && source->state == AL_PLAYING) { source->state = AL_STOPPED; - ATOMIC_STORE(&source->current_buffer, NULL); - ATOMIC_STORE(&source->position, 0); - ATOMIC_STORE(&source->position_fraction, 0); + ATOMIC_STORE(&source->current_buffer, NULL, almemory_order_relaxed); + ATOMIC_STORE(&source->position, 0, almemory_order_relaxed); + ATOMIC_STORE(&source->position_fraction, 0, almemory_order_release); } voice++; diff --git a/Alc/helpers.c b/Alc/helpers.c index 0a6982e9..ef0c8e88 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -558,7 +558,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) vector_al_string results = VECTOR_INIT_STATIC(); size_t i; - while(ATOMIC_EXCHANGE(uint, &search_lock, 1) == 1) + while(ATOMIC_EXCHANGE_SEQ(uint, &search_lock, 1) == 1) althrd_yield(); /* If the path is absolute, use it directly. */ @@ -629,7 +629,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) al_string_deinit(&path); } - ATOMIC_STORE(&search_lock, 0); + ATOMIC_STORE_SEQ(&search_lock, 0); return results; } @@ -834,7 +834,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) static RefCount search_lock; vector_al_string results = VECTOR_INIT_STATIC(); - while(ATOMIC_EXCHANGE(uint, &search_lock, 1) == 1) + while(ATOMIC_EXCHANGE_SEQ(uint, &search_lock, 1) == 1) althrd_yield(); if(subdir[0] == '/') @@ -903,7 +903,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) al_string_deinit(&path); } - ATOMIC_STORE(&search_lock, 0); + ATOMIC_STORE_SEQ(&search_lock, 0); return results; } diff --git a/Alc/mixer.c b/Alc/mixer.c index dba429a0..be6a137c 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -532,7 +532,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } tmpiter = tmpiter->next; if(!tmpiter && Looping) - tmpiter = ATOMIC_LOAD(&Source->queue); + tmpiter = ATOMIC_LOAD(&Source->queue, almemory_order_acquire); else if(!tmpiter) { SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize); @@ -675,7 +675,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam if(!(BufferListItem=BufferListItem->next)) { if(Looping) - BufferListItem = ATOMIC_LOAD(&Source->queue); + BufferListItem = ATOMIC_LOAD(&Source->queue, almemory_order_acquire); else { State = AL_STOPPED; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 4f1601ed..a7bc0f32 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -114,11 +114,11 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo } if(last != NULL) { - ALeffectslot *root = ATOMIC_LOAD(&context->ActiveAuxSlotList); + ALeffectslot *root = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); do { ATOMIC_STORE(&last->next, root, almemory_order_relaxed); - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALeffectslot*, &context->ActiveAuxSlotList, - &root, first)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALeffectslot*, &context->ActiveAuxSlotList, + &root, first)); } done: @@ -436,14 +436,14 @@ static void RemoveEffectSlotList(ALCcontext *context, ALeffectslot *slot) ALeffectslot *root, *next; root = slot; - next = ATOMIC_LOAD(&slot->next); - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) + next = ATOMIC_LOAD_SEQ(&slot->next); + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) { ALeffectslot *cur; do { cur = root; root = slot; - } while(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &cur->next, &root, next)); + } while(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALeffectslot*, &cur->next, &root, next)); } /* Wait for any mix that may be using these effect slots to finish. */ while((ReadRef(&device->MixCount)&1) != 0) @@ -527,7 +527,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e EffectSlot->Effect.Props = effect->Props; /* Remove state references from old effect slot property updates. */ - props = ATOMIC_LOAD(&EffectSlot->FreeList); + props = ATOMIC_LOAD_SEQ(&EffectSlot->FreeList); while(props) { State = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); @@ -605,7 +605,7 @@ void DeinitEffectSlot(ALeffectslot *slot) ALeffectState *state; size_t count = 0; - props = ATOMIC_LOAD(&slot->Update); + props = ATOMIC_LOAD_SEQ(&slot->Update); if(props) { state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); @@ -671,10 +671,10 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* If there was an unused update container, put it back in the * freelist. */ - struct ALeffectslotProps *first = ATOMIC_LOAD(&slot->FreeList); + struct ALeffectslotProps *first = ATOMIC_LOAD_SEQ(&slot->FreeList); do { ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, + } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALeffectslotProps*, &slot->FreeList, &first, props) == 0); } @@ -687,7 +687,7 @@ void UpdateAllEffectSlotProps(ALCcontext *context) ALeffectslot *slot; LockEffectSlotsRead(context); - slot = ATOMIC_LOAD(&context->ActiveAuxSlotList); + slot = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); while(slot) { if(slot->NeedsUpdate) diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 193cfeaa..24470d64 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -161,7 +161,7 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoi if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(srctype, &align) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(srctype) @@ -311,7 +311,7 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); WriteLock(&albuf->lock); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(srctype, &align) == AL_FALSE) { WriteUnlock(&albuf->lock); @@ -390,7 +390,7 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if((samples%align) != 0) @@ -428,7 +428,7 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); WriteLock(&albuf->lock); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) { WriteUnlock(&albuf->lock); @@ -483,7 +483,7 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); ReadLock(&albuf->lock); - align = ATOMIC_LOAD(&albuf->PackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->PackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) { ReadUnlock(&albuf->lock); @@ -630,13 +630,13 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - ATOMIC_STORE(&albuf->UnpackAlign, value); + ATOMIC_STORE_SEQ(&albuf->UnpackAlign, value); break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - ATOMIC_STORE(&albuf->PackAlign, value); + ATOMIC_STORE_SEQ(&albuf->PackAlign, value); break; default: @@ -878,11 +878,11 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value break; case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: - *value = ATOMIC_LOAD(&albuf->UnpackAlign); + *value = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: - *value = ATOMIC_LOAD(&albuf->PackAlign); + *value = ATOMIC_LOAD_SEQ(&albuf->PackAlign); break; default: diff --git a/OpenAL32/alError.c b/OpenAL32/alError.c index b38d8dfe..6b7684ce 100644 --- a/OpenAL32/alError.c +++ b/OpenAL32/alError.c @@ -46,7 +46,7 @@ ALvoid alSetError(ALCcontext *Context, ALenum errorCode) raise(SIGTRAP); #endif } - ATOMIC_COMPARE_EXCHANGE_STRONG(ALenum, &Context->LastError, &curerr, errorCode); + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &Context->LastError, &curerr, errorCode); } AL_API ALenum AL_APIENTRY alGetError(void) @@ -69,7 +69,7 @@ AL_API ALenum AL_APIENTRY alGetError(void) return AL_INVALID_OPERATION; } - errorCode = ATOMIC_EXCHANGE(ALenum, &Context->LastError, AL_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(ALenum, &Context->LastError, AL_NO_ERROR); ALCcontext_DecRef(Context); diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 4e99f24e..f05c20d1 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -506,10 +506,10 @@ void UpdateListenerProps(ALCcontext *context) /* If there was an unused update container, put it back in the * freelist. */ - struct ALlistenerProps *first = ATOMIC_LOAD(&listener->FreeList); + struct ALlistenerProps *first = ATOMIC_LOAD_SEQ(&listener->FreeList); do { ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, + } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALlistenerProps*, &listener->FreeList, &first, props) == 0); } } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 81cd44cd..9f60c545 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -658,7 +658,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); WriteLock(&Source->queue_lock); - ATOMIC_STORE(&Source->looping, *values); + ATOMIC_STORE_SEQ(&Source->looping, *values); WriteUnlock(&Source->queue_lock); return AL_TRUE; @@ -700,8 +700,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->SourceType = AL_UNDETERMINED; newlist = NULL; } - oldlist = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, newlist); - ATOMIC_STORE(&Source->current_buffer, newlist); + oldlist = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &Source->queue, newlist); + ATOMIC_STORE_SEQ(&Source->current_buffer, newlist); WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); @@ -1097,7 +1097,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SEC_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1214,13 +1214,14 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_LOOPING: - *values = ATOMIC_LOAD(&Source->looping); + *values = ATOMIC_LOAD_SEQ(&Source->looping); return AL_TRUE; case AL_BUFFER: ReadLock(&Source->queue_lock); - BufferList = (Source->SourceType == AL_STATIC) ? ATOMIC_LOAD(&Source->queue) : - ATOMIC_LOAD(&Source->current_buffer); + BufferList = (Source->SourceType == AL_STATIC) ? + ATOMIC_LOAD_SEQ(&Source->queue) : + ATOMIC_LOAD_SEQ(&Source->current_buffer); *values = (BufferList && BufferList->buffer) ? BufferList->buffer->id : 0; ReadUnlock(&Source->queue_lock); return AL_TRUE; @@ -1231,7 +1232,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BYTE_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1270,7 +1271,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SAMPLE_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1286,7 +1287,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_QUEUED: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1301,7 +1302,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_PROCESSED: ReadLock(&Source->queue_lock); - if(ATOMIC_LOAD(&Source->looping) || Source->SourceType != AL_STREAMING) + if(ATOMIC_LOAD_SEQ(&Source->looping) || Source->SourceType != AL_STREAMING) { /* Buffers on a looping source are in a perpetual state of * PENDING, so don't report any as PROCESSED */ @@ -1309,8 +1310,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } else { - const ALbufferlistitem *BufferList = ATOMIC_LOAD(&Source->queue); - const ALbufferlistitem *Current = ATOMIC_LOAD(&Source->current_buffer); + const ALbufferlistitem *BufferList = ATOMIC_LOAD_SEQ(&Source->queue); + const ALbufferlistitem *Current = ATOMIC_LOAD_SEQ(&Source->current_buffer); ALsizei played = 0; while(BufferList && BufferList != Current) { @@ -2499,7 +2500,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu } /* Check for a valid Buffer, for its frequency and format */ - BufferList = ATOMIC_LOAD(&source->queue); + BufferList = ATOMIC_LOAD_SEQ(&source->queue); while(BufferList) { if(BufferList->buffer) @@ -2588,7 +2589,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu source->SourceType = AL_STREAMING; BufferList = NULL; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALbufferlistitem*, &source->queue, &BufferList, BufferListStart)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALbufferlistitem*, &source->queue, + &BufferList, BufferListStart)) { /* Queue head is not NULL, append to the end of the queue */ while(BufferList->next != NULL) @@ -2599,7 +2601,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu * buffers. */ BufferList = NULL; - ATOMIC_COMPARE_EXCHANGE_STRONG(ALbufferlistitem*, &source->current_buffer, &BufferList, BufferListStart); + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALbufferlistitem*, &source->current_buffer, + &BufferList, BufferListStart); WriteUnlock(&source->queue_lock); done: @@ -2630,7 +2633,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); WriteLock(&source->queue_lock); - if(ATOMIC_LOAD(&source->looping) || source->SourceType != AL_STREAMING) + if(ATOMIC_LOAD_SEQ(&source->looping) || source->SourceType != AL_STREAMING) { WriteUnlock(&source->queue_lock); /* Trying to unqueue buffers on a looping or non-streaming source. */ @@ -2638,8 +2641,8 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } /* Find the new buffer queue head */ - OldTail = ATOMIC_LOAD(&source->queue); - Current = ATOMIC_LOAD(&source->current_buffer); + OldTail = ATOMIC_LOAD_SEQ(&source->queue); + Current = ATOMIC_LOAD_SEQ(&source->current_buffer); if(OldTail != Current) { for(i = 1;i < nb;i++) @@ -2657,7 +2660,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } /* Swap it, and cut the new head from the old. */ - OldHead = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, OldTail->next); + OldHead = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &source->queue, OldTail->next); if(OldTail->next) { ALCdevice *device = context->Device; @@ -2788,7 +2791,7 @@ static void DeinitSource(ALsource *source) size_t count = 0; size_t i; - props = ATOMIC_LOAD(&source->Update); + props = ATOMIC_LOAD_SEQ(&source->Update); if(props) al_free(props); props = ATOMIC_LOAD(&source->FreeList, almemory_order_relaxed); @@ -2806,7 +2809,7 @@ static void DeinitSource(ALsource *source) if(count > 3) WARN("Freed "SZFMT" Source property objects\n", count); - BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, NULL); + BufferList = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &source->queue, NULL); while(BufferList != NULL) { ALbufferlistitem *next = BufferList->next; @@ -2910,7 +2913,7 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends) /* If there was an unused update container, put it back in the * freelist. */ - struct ALsourceProps *first = ATOMIC_LOAD(&source->FreeList); + struct ALsourceProps *first = ATOMIC_LOAD_SEQ(&source->FreeList); do { ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, @@ -2956,7 +2959,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) /* Check that there is a queue containing at least one valid, non zero * length Buffer. */ - BufferList = ATOMIC_LOAD(&Source->queue); + BufferList = ATOMIC_LOAD_SEQ(&Source->queue); while(BufferList) { ALbuffer *buffer; @@ -3052,7 +3055,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_INITIAL) { Source->state = AL_STOPPED; - ATOMIC_STORE(&Source->current_buffer, NULL); + ATOMIC_STORE_SEQ(&Source->current_buffer, NULL); } Source->OffsetType = AL_NONE; Source->Offset = 0.0; @@ -3062,10 +3065,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_INITIAL) { Source->state = AL_INITIAL; - ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD(&Source->queue), + ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD_SEQ(&Source->queue), almemory_order_relaxed); ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, 0); + ATOMIC_STORE_SEQ(&Source->position_fraction, 0); } Source->OffsetType = AL_NONE; Source->Offset = 0.0; @@ -3304,7 +3307,7 @@ ALboolean ApplyOffset(ALsource *Source) return AL_FALSE; totalBufferLen = 0; - BufferList = ATOMIC_LOAD(&Source->queue); + BufferList = ATOMIC_LOAD_SEQ(&Source->queue); while(BufferList && totalBufferLen <= offset) { Buffer = BufferList->buffer; @@ -3343,7 +3346,7 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac) ALdouble dbloff, dblfrac; /* Find the first valid Buffer in the Queue */ - BufferList = ATOMIC_LOAD(&Source->queue); + BufferList = ATOMIC_LOAD_SEQ(&Source->queue); while(BufferList) { if(BufferList->buffer) diff --git a/OpenAL32/alThunk.c b/OpenAL32/alThunk.c index 72fc0dcb..d3892c97 100644 --- a/OpenAL32/alThunk.c +++ b/OpenAL32/alThunk.c @@ -54,7 +54,7 @@ ALenum NewThunkEntry(ALuint *index) ReadLock(&ThunkLock); for(i = 0;i < ThunkArraySize;i++) { - if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE) == AL_FALSE) + if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE) { ReadUnlock(&ThunkLock); *index = i+1; @@ -69,7 +69,7 @@ ALenum NewThunkEntry(ALuint *index) */ for(;i < ThunkArraySize;i++) { - if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE) == AL_FALSE) + if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE) { WriteUnlock(&ThunkLock); *index = i+1; @@ -89,7 +89,7 @@ ALenum NewThunkEntry(ALuint *index) ThunkArray = NewList; ThunkArraySize *= 2; - ATOMIC_STORE(&ThunkArray[i], AL_TRUE); + ATOMIC_STORE_SEQ(&ThunkArray[i], AL_TRUE); WriteUnlock(&ThunkLock); *index = i+1; @@ -100,6 +100,6 @@ void FreeThunkEntry(ALuint index) { ReadLock(&ThunkLock); if(index > 0 && index <= ThunkArraySize) - ATOMIC_STORE(&ThunkArray[index-1], AL_FALSE); + ATOMIC_STORE_SEQ(&ThunkArray[index-1], AL_FALSE); ReadUnlock(&ThunkLock); } diff --git a/include/atomic.h b/include/atomic.h index 4dff05da..4783defe 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -28,26 +28,20 @@ extern "C" { #define ATOMIC_INIT_STATIC(_newval) ATOMIC_VAR_INIT(_newval) /*#define ATOMIC_FLAG_INIT ATOMIC_FLAG_INIT*/ -#define PARAM2(f, a, b, ...) (f((a), (b))) -#define PARAM3(f, a, b, c, ...) (f((a), (b), (c))) -#define PARAM5(f, a, b, c, d, e, ...) (f((a), (b), (c), (d), (e))) +#define ATOMIC_LOAD(_val, _MO) atomic_load_explicit(_val, _MO) +#define ATOMIC_STORE(_val, _newval, _MO) atomic_store_explicit(_val, _newval, _MO) -#define ATOMIC_LOAD(...) PARAM2(atomic_load_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_STORE(...) PARAM3(atomic_store_explicit, __VA_ARGS__, memory_order_seq_cst) +#define ATOMIC_ADD(_val, _incr, _MO) atomic_fetch_add_explicit(_val, _incr, _MO) +#define ATOMIC_SUB(_val, _decr, _MO) atomic_fetch_sub_explicit(_val, _decr, _MO) -#define ATOMIC_ADD(...) PARAM3(atomic_fetch_add_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_SUB(...) PARAM3(atomic_fetch_sub_explicit, __VA_ARGS__, memory_order_seq_cst) +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) atomic_exchange_explicit(_val, _newval, _MO) +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _orig, _newval, _MO1, _MO2) \ + atomic_compare_exchange_strong_explicit(_val, _orig, _newval, _MO1, _MO2) +#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _orig, _newval, _MO1, _MO2) \ + atomic_compare_exchange_weak_explicit(_val, _orig, _newval, _MO1, _MO2) -#define ATOMIC_EXCHANGE(T, ...) PARAM3(atomic_exchange_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, ...) \ - PARAM5(atomic_compare_exchange_strong_explicit, __VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst) -#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, ...) \ - PARAM5(atomic_compare_exchange_weak_explicit, __VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst) - -#define ATOMIC_FLAG_TEST_AND_SET(...) \ - PARAM2(atomic_flag_test_and_set_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_FLAG_CLEAR(...) \ - PARAM2(atomic_flag_clear_explicit, __VA_ARGS__, memory_order_seq_cst) +#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) atomic_flag_test_and_set_explicit(_val, _MO) +#define ATOMIC_FLAG_CLEAR(_val, _MO) atomic_flag_clear_explicit(_val, _MO) #define ATOMIC_THREAD_FENCE atomic_thread_fence @@ -70,36 +64,36 @@ enum almemory_order { #define ATOMIC_INIT_STATIC(_newval) {(_newval)} #define ATOMIC_FLAG_INIT ATOMIC_INIT_STATIC(0) -#define ATOMIC_LOAD(_val, ...) __extension__({ \ +#define ATOMIC_LOAD(_val, _MO) __extension__({ \ __typeof((_val)->value) _r = (_val)->value; \ __asm__ __volatile__("" ::: "memory"); \ _r; \ }) -#define ATOMIC_STORE(_val, _newval, ...) do { \ +#define ATOMIC_STORE(_val, _newval, _MO) do { \ __asm__ __volatile__("" ::: "memory"); \ (_val)->value = (_newval); \ } while(0) -#define ATOMIC_ADD(_val, _incr, ...) __sync_fetch_and_add(&(_val)->value, (_incr)) -#define ATOMIC_SUB(_val, _decr, ...) __sync_fetch_and_sub(&(_val)->value, (_decr)) +#define ATOMIC_ADD(_val, _incr, _MO) __sync_fetch_and_add(&(_val)->value, (_incr)) +#define ATOMIC_SUB(_val, _decr, _MO) __sync_fetch_and_sub(&(_val)->value, (_decr)) -#define ATOMIC_EXCHANGE(T, _val, _newval, ...) __extension__({ \ +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) __extension__({ \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ __asm__ __volatile__("" ::: "memory"); \ __sync_lock_test_and_set(&(_val)->value, (_newval)); \ }) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) __extension__({ \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) __extension__({ \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ T _o = *(_oldval); \ *(_oldval) = __sync_val_compare_and_swap(&(_val)->value, _o, (_newval)); \ *(_oldval) == _o; \ }) -#define ATOMIC_FLAG_TEST_AND_SET(_val, ...) __extension__({ \ +#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) __extension__({ \ __asm__ __volatile__("" ::: "memory"); \ __sync_lock_test_and_set(&(_val)->value, 1); \ }) -#define ATOMIC_FLAG_CLEAR(_val, ...) __extension__({ \ +#define ATOMIC_FLAG_CLEAR(_val, _MO) __extension__({ \ __sync_lock_release(&(_val)->value); \ __asm__ __volatile__("" ::: "memory"); \ }) @@ -156,24 +150,24 @@ enum almemory_order { #define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0) #define ATOMIC_INIT_STATIC(_newval) {(_newval)} -#define ATOMIC_LOAD(_val, ...) __extension__({ \ +#define ATOMIC_LOAD(_val, _MO) __extension__({ \ __typeof((_val)->value) _r = (_val)->value; \ __asm__ __volatile__("" ::: "memory"); \ _r; \ }) -#define ATOMIC_STORE(_val, _newval, ...) do { \ +#define ATOMIC_STORE(_val, _newval, _MO) do { \ __asm__ __volatile__("" ::: "memory"); \ (_val)->value = (_newval); \ } while(0) -#define ATOMIC_ADD(_val, _incr, ...) __extension__({ \ +#define ATOMIC_ADD(_val, _incr, _MO) __extension__({ \ static_assert(sizeof((_val)->value)==4 || sizeof((_val)->value)==8, "Unsupported size!"); \ __typeof((_val)->value) _r; \ if(sizeof((_val)->value) == 4) WRAP_ADD("l", _r, &(_val)->value, _incr); \ else if(sizeof((_val)->value) == 8) WRAP_ADD("q", _r, &(_val)->value, _incr); \ _r; \ }) -#define ATOMIC_SUB(_val, _decr, ...) __extension__({ \ +#define ATOMIC_SUB(_val, _decr, _MO) __extension__({ \ static_assert(sizeof((_val)->value)==4 || sizeof((_val)->value)==8, "Unsupported size!"); \ __typeof((_val)->value) _r; \ if(sizeof((_val)->value) == 4) WRAP_SUB("l", _r, &(_val)->value, _decr); \ @@ -181,7 +175,7 @@ enum almemory_order { _r; \ }) -#define ATOMIC_EXCHANGE(T, _val, _newval, ...) __extension__({ \ +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) __extension__({ \ static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ T _r; \ @@ -189,7 +183,7 @@ enum almemory_order { else if(sizeof(T) == 8) WRAP_XCHG("q", _r, &(_val)->value, (T)(_newval)); \ _r; \ }) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) __extension__({ \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) __extension__({ \ static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ T _old = *(_oldval); \ @@ -279,27 +273,27 @@ enum almemory_order { #define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0) #define ATOMIC_INIT_STATIC(_newval) {(_newval)} -#define ATOMIC_LOAD(_val, ...) ((_val)->value) -#define ATOMIC_STORE(_val, _newval, ...) do { \ +#define ATOMIC_LOAD(_val, _MO) ((_val)->value) +#define ATOMIC_STORE(_val, _newval, _MO) do { \ (_val)->value = (_newval); \ } while(0) int _al_invalid_atomic_size(); /* not defined */ -#define ATOMIC_ADD(_val, _incr, ...) \ +#define ATOMIC_ADD(_val, _incr, _MO) \ ((sizeof((_val)->value)==4) ? WRAP_ADDSUB(LONG, AtomicAdd32, &(_val)->value, (_incr)) : \ (sizeof((_val)->value)==8) ? WRAP_ADDSUB(LONGLONG, AtomicAdd64, &(_val)->value, (_incr)) : \ _al_invalid_atomic_size()) -#define ATOMIC_SUB(_val, _decr, ...) \ +#define ATOMIC_SUB(_val, _decr, _MO) \ ((sizeof((_val)->value)==4) ? WRAP_ADDSUB(LONG, AtomicSub32, &(_val)->value, (_decr)) : \ (sizeof((_val)->value)==8) ? WRAP_ADDSUB(LONGLONG, AtomicSub64, &(_val)->value, (_decr)) : \ _al_invalid_atomic_size()) -#define ATOMIC_EXCHANGE(T, _val, _newval, ...) \ +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) \ ((sizeof(T)==4) ? WRAP_XCHG(T, AtomicSwap32, &(_val)->value, (_newval)) : \ (sizeof(T)==8) ? WRAP_XCHG(T, AtomicSwap64, &(_val)->value, (_newval)) : \ (T)_al_invalid_atomic_size()) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) \ ((sizeof(T)==4) ? WRAP_CMPXCHG(T, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \ (sizeof(T)==8) ? WRAP_CMPXCHG(T, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \ (bool)_al_invalid_atomic_size()) @@ -333,7 +327,7 @@ int _al_invalid_atomic_size(); /* not defined */ #define ATOMIC_FLAG_TEST_AND_SET(...) (0) #define ATOMIC_FLAG_CLEAR(...) ((void)0) -#define ATOMIC_THREAD_FENCE ((void)0) +#define ATOMIC_THREAD_FENCE(...) ((void)0) #endif /* If no weak cmpxchg is provided (not all systems will have one), substitute a @@ -348,24 +342,35 @@ int _al_invalid_atomic_size(); /* not defined */ #ifndef ATOMIC_FLAG #define ATOMIC_FLAG ATOMIC(int) #define ATOMIC_FLAG_INIT ATOMIC_INIT_STATIC(0) -#define ATOMIC_FLAG_TEST_AND_SET_(_val, ...) ATOMIC_EXCHANGE(int, _val, 1, __VA_ARGS__) -#define ATOMIC_FLAG_TEST_AND_SET(...) ATOMIC_FLAG_TEST_AND_SET_(__VA_ARGS__, almemory_order_seq_cst) -#define ATOMIC_FLAG_CLEAR_(_val, ...) ATOMIC_STORE(_val, 0, __VA_ARGS__) -#define ATOMIC_FLAG_CLEAR(...) ATOMIC_FLAG_CLEAR_(__VA_ARGS__, almemory_order_seq_cst) +#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) ATOMIC_EXCHANGE(int, _val, 1, _MO) +#define ATOMIC_FLAG_CLEAR(_val, _MO) ATOMIC_STORE(_val, 0, _MO) #endif +#define ATOMIC_LOAD_SEQ(_val) ATOMIC_LOAD(_val, almemory_order_seq_cst) +#define ATOMIC_STORE_SEQ(_val, _newval) ATOMIC_STORE(_val, _newval, almemory_order_seq_cst) + +#define ATOMIC_ADD_SEQ(_val, _incr) ATOMIC_ADD(_val, _incr, almemory_order_seq_cst) +#define ATOMIC_SUB_SEQ(_val, _decr) ATOMIC_SUB(_val, _decr, almemory_order_seq_cst) + +#define ATOMIC_EXCHANGE_SEQ(T, _val, _newval) ATOMIC_EXCHANGE(T, _val, _newval, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(T, _val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(T, _val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) + + typedef unsigned int uint; typedef ATOMIC(uint) RefCount; inline void InitRef(RefCount *ptr, uint value) { ATOMIC_INIT(ptr, value); } inline uint ReadRef(RefCount *ptr) -{ return ATOMIC_LOAD(ptr); } +{ return ATOMIC_LOAD_SEQ(ptr); } inline uint IncrementRef(RefCount *ptr) -{ return ATOMIC_ADD(ptr, 1)+1; } +{ return ATOMIC_ADD_SEQ(ptr, 1)+1; } inline uint DecrementRef(RefCount *ptr) -{ return ATOMIC_SUB(ptr, 1)-1; } +{ return ATOMIC_SUB_SEQ(ptr, 1)-1; } #ifdef __cplusplus -- 2.11.4.GIT