aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c36
-rw-r--r--Alc/ALu.c12
-rw-r--r--Alc/backends/opensl.c4
-rw-r--r--Alc/backends/oss.c4
-rw-r--r--Alc/backends/solaris.c2
-rw-r--r--Alc/helpers.c4
-rw-r--r--OpenAL32/alAuxEffectSlot.c18
-rw-r--r--OpenAL32/alError.c4
-rw-r--r--OpenAL32/alListener.c7
-rw-r--r--OpenAL32/alSource.c19
-rw-r--r--include/atomic.h133
11 files changed, 135 insertions, 108 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 2a636c59..cc9aa5c3 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1247,7 +1247,7 @@ static void alc_cleanup(void)
free(alcCaptureDefaultDeviceSpecifier);
alcCaptureDefaultDeviceSpecifier = NULL;
- if((dev=ATOMIC_EXCHANGE_SEQ(ALCdevice*, &DeviceList, NULL)) != NULL)
+ if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
{
ALCuint num = 0;
do {
@@ -1678,7 +1678,7 @@ void ALCcontext_DeferUpdates(ALCcontext *context)
void ALCcontext_ProcessUpdates(ALCcontext *context)
{
ReadLock(&context->PropLock);
- if(ATOMIC_EXCHANGE_SEQ(ALenum, &context->DeferUpdates, AL_FALSE))
+ if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
{
/* Tell the mixer to stop applying updates, then wait for any active
* updating to finish, before providing updates.
@@ -2225,11 +2225,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
* number of auxiliary sends changed. Playing (or paused) sources
* will have updates respecified in UpdateAllSourceProps.
*/
- props = ATOMIC_EXCHANGE_SEQ(struct ALsourceProps*, &source->Update, NULL);
+ props = ATOMIC_EXCHANGE_PTR_SEQ(&source->Update, NULL);
al_free(props);
- props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->FreeList, NULL,
- almemory_order_relaxed);
+ props = ATOMIC_EXCHANGE_PTR(&source->FreeList, NULL, almemory_order_relaxed);
while(props)
{
struct ALsourceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
@@ -2489,8 +2488,7 @@ static void FreeContext(ALCcontext *context)
TRACE("%p\n", context);
- auxslots = ATOMIC_EXCHANGE(struct ALeffectslotArray*, &context->ActiveAuxSlots,
- NULL, almemory_order_relaxed);
+ auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
al_free(auxslots);
if(context->SourceMap.size > 0)
@@ -2557,13 +2555,13 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
}
origctx = context;
- if(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &GlobalContext, &origctx, NULL))
+ if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
ALCcontext_DecRef(context);
ALCdevice_Lock(device);
origctx = context;
newhead = context->next;
- if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &device->ContextList, &origctx, newhead))
+ if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
{
ALCcontext *volatile*list = &origctx->next;
while(*list)
@@ -2750,11 +2748,11 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
if(VerifyDevice(&device))
{
- errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &device->LastError, ALC_NO_ERROR);
+ errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
ALCdevice_DecRef(device);
}
else
- errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
+ errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
return errorCode;
}
@@ -3549,8 +3547,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
do {
ALContext->next = head;
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCcontext*,
- &device->ContextList, &head, ALContext) == 0);
+ } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
+ ALContext) == 0);
}
almtx_unlock(&device->BackendLock);
@@ -3628,7 +3626,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
return ALC_FALSE;
}
/* context's reference count is already incremented */
- context = ATOMIC_EXCHANGE_SEQ(ALCcontext*, &GlobalContext, context);
+ context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
if(context) ALCcontext_DecRef(context);
if((context=altss_get(LocalContext)) != NULL)
@@ -3937,7 +3935,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
do {
device->next = head;
- } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
+ } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
}
TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
@@ -3968,7 +3966,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
almtx_lock(&device->BackendLock);
origdev = device;
- if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next))
+ if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
{
ALCdevice *volatile*list = &origdev->next;
while(*list)
@@ -4113,7 +4111,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
do {
device->next = head;
- } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
+ } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
}
TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
@@ -4138,7 +4136,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
}
origdev = device;
- if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next))
+ if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
{
ALCdevice *volatile*list = &origdev->next;
while(*list)
@@ -4334,7 +4332,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
do {
device->next = head;
- } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
+ } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
}
TRACE("Created device %p\n", device);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 4f41d012..89689fba 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -241,7 +241,7 @@ static ALboolean CalcListenerParams(ALCcontext *Context)
struct ALlistenerProps *props;
aluVector vel;
- props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel);
+ props = ATOMIC_EXCHANGE_PTR(&Listener->Update, NULL, almemory_order_acq_rel);
if(!props) return AL_FALSE;
/* AT then UP */
@@ -291,7 +291,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
struct ALeffectslotProps *props;
ALeffectState *state;
- props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel);
+ props = ATOMIC_EXCHANGE_PTR(&slot->Update, NULL, almemory_order_acq_rel);
if(!props) return AL_FALSE;
slot->Params.Gain = props->Gain;
@@ -1252,7 +1252,7 @@ static void CalcSourceParams(ALvoice *voice, ALsource *source, ALCcontext *conte
const ALbufferlistitem *BufferListItem;
struct ALsourceProps *props;
- props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel);
+ props = ATOMIC_EXCHANGE_PTR(&source->Update, NULL, almemory_order_acq_rel);
if(!props && !force) return;
if(props)
@@ -1607,14 +1607,14 @@ void aluHandleDisconnect(ALCdevice *device)
voice_end = voice + Context->VoiceCount;
while(voice != voice_end)
{
- ALsource *source = ATOMIC_EXCHANGE(ALsource*, &(*voice)->Source, NULL,
- almemory_order_acq_rel);
+ ALsource *source = ATOMIC_EXCHANGE_PTR(&(*voice)->Source, NULL,
+ almemory_order_acq_rel);
ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release);
if(source)
{
ALenum playing = AL_PLAYING;
- ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED);
+ (void)(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(&source->state, &playing, AL_STOPPED));
}
voice++;
diff --git a/Alc/backends/opensl.c b/Alc/backends/opensl.c
index 622437b8..4e295f23 100644
--- a/Alc/backends/opensl.c
+++ b/Alc/backends/opensl.c
@@ -149,7 +149,7 @@ typedef struct ALCopenslPlayback {
ALsizei mFrameSize;
- ATOMIC(ALboolean) mKillNow;
+ ATOMIC(ALenum) mKillNow;
althrd_t mThread;
} ALCopenslPlayback;
@@ -637,7 +637,7 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
SLresult result;
int res;
- if(ATOMIC_EXCHANGE_SEQ(ALboolean, &self->mKillNow, AL_TRUE))
+ if(ATOMIC_EXCHANGE_SEQ(&self->mKillNow, AL_TRUE))
return;
/* Lock the backend to ensure we don't flag the mixer to die and signal the
diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c
index 6774a789..33ea55eb 100644
--- a/Alc/backends/oss.c
+++ b/Alc/backends/oss.c
@@ -491,7 +491,7 @@ static void ALCplaybackOSS_stop(ALCplaybackOSS *self)
{
int res;
- if(ATOMIC_EXCHANGE_SEQ(ALenum, &self->killNow, AL_TRUE))
+ if(ATOMIC_EXCHANGE_SEQ(&self->killNow, AL_TRUE))
return;
althrd_join(self->thread, &res);
@@ -745,7 +745,7 @@ static void ALCcaptureOSS_stop(ALCcaptureOSS *self)
{
int res;
- if(ATOMIC_EXCHANGE_SEQ(ALenum, &self->killNow, AL_TRUE))
+ if(ATOMIC_EXCHANGE_SEQ(&self->killNow, AL_TRUE))
return;
althrd_join(self->thread, &res);
diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c
index 5b3f6136..5dfb5084 100644
--- a/Alc/backends/solaris.c
+++ b/Alc/backends/solaris.c
@@ -285,7 +285,7 @@ static void ALCsolarisBackend_stop(ALCsolarisBackend *self)
{
int res;
- if(ATOMIC_EXCHANGE_SEQ(int, &self->killNow, AL_TRUE))
+ if(ATOMIC_EXCHANGE_SEQ(&self->killNow, AL_TRUE))
return;
althrd_join(self->thread, &res);
diff --git a/Alc/helpers.c b/Alc/helpers.c
index 5d23c3a7..8e685c75 100644
--- a/Alc/helpers.c
+++ b/Alc/helpers.c
@@ -564,7 +564,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir)
vector_al_string results = VECTOR_INIT_STATIC();
size_t i;
- while(ATOMIC_EXCHANGE_SEQ(uint, &search_lock, 1) == 1)
+ while(ATOMIC_EXCHANGE_SEQ(&search_lock, 1) == 1)
althrd_yield();
/* If the path is absolute, use it directly. */
@@ -840,7 +840,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_SEQ(uint, &search_lock, 1) == 1)
+ while(ATOMIC_EXCHANGE_SEQ(&search_lock, 1) == 1)
althrd_yield();
if(subdir[0] == '/')
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index 743fac14..de7de943 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -126,9 +126,8 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
if(curarray)
memcpy(newarray->slot+n, curarray->slot, sizeof(ALeffectslot*)*curarray->count);
- newarray = ATOMIC_EXCHANGE(struct ALeffectslotArray*,
- &context->ActiveAuxSlots, newarray, almemory_order_acq_rel
- );
+ newarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray,
+ almemory_order_acq_rel);
device = context->Device;
while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1))
althrd_yield();
@@ -187,9 +186,8 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *
newarray->slot[i++] = slot;
}
- newarray = ATOMIC_EXCHANGE(struct ALeffectslotArray*,
- &context->ActiveAuxSlots, newarray, almemory_order_acq_rel
- );
+ newarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray,
+ almemory_order_acq_rel);
device = context->Device;
while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1))
althrd_yield();
@@ -668,9 +666,8 @@ void UpdateEffectSlotProps(ALeffectslot *slot)
struct ALeffectslotProps *next;
do {
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*,
- &slot->FreeList, &props, next, almemory_order_seq_cst,
- almemory_order_acquire) == 0);
+ } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&slot->FreeList, &props, next,
+ almemory_order_seq_cst, almemory_order_acquire) == 0);
}
/* Copy in current property values. */
@@ -687,8 +684,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot)
props->State = slot->Effect.State;
/* Set the new container for updating internal parameters. */
- props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props,
- almemory_order_acq_rel);
+ props = ATOMIC_EXCHANGE_PTR(&slot->Update, props, almemory_order_acq_rel);
if(props)
{
/* If there was an unused update container, put it back in the
diff --git a/OpenAL32/alError.c b/OpenAL32/alError.c
index 19fcaa6d..6c953977 100644
--- a/OpenAL32/alError.c
+++ b/OpenAL32/alError.c
@@ -49,7 +49,7 @@ ALvoid alSetError(ALCcontext *Context, ALenum errorCode)
#endif
}
- ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &Context->LastError, &curerr, errorCode);
+ (void)(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(&Context->LastError, &curerr, errorCode));
}
AL_API ALenum AL_APIENTRY alGetError(void)
@@ -74,7 +74,7 @@ AL_API ALenum AL_APIENTRY alGetError(void)
return AL_INVALID_OPERATION;
}
- errorCode = ATOMIC_EXCHANGE_SEQ(ALenum, &Context->LastError, AL_NO_ERROR);
+ errorCode = ATOMIC_EXCHANGE_SEQ(&Context->LastError, AL_NO_ERROR);
ALCcontext_DecRef(Context);
diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c
index e3d71435..d117c0ca 100644
--- a/OpenAL32/alListener.c
+++ b/OpenAL32/alListener.c
@@ -468,9 +468,8 @@ void UpdateListenerProps(ALCcontext *context)
struct ALlistenerProps *next;
do {
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*,
- &listener->FreeList, &props, next, almemory_order_seq_cst,
- almemory_order_acquire) == 0);
+ } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&listener->FreeList, &props, next,
+ almemory_order_seq_cst, almemory_order_acquire) == 0);
}
/* Copy in current property values. */
@@ -500,7 +499,7 @@ void UpdateListenerProps(ALCcontext *context)
props->DistanceModel = context->DistanceModel;;
/* Set the new container for updating internal parameters. */
- props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &listener->Update, props, almemory_order_acq_rel);
+ props = ATOMIC_EXCHANGE_PTR(&listener->Update, props, almemory_order_acq_rel);
if(props)
{
/* If there was an unused update container, put it back in the
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index a8c4ce2f..040078df 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -158,7 +158,7 @@ static inline ALenum GetSourceState(ALsource *source, ALvoice *voice)
if(!voice)
{
ALenum state = AL_PLAYING;
- if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALenum, &source->state, &state, AL_STOPPED,
+ if(ATOMIC_COMPARE_EXCHANGE_STRONG(&source->state, &state, AL_STOPPED,
almemory_order_acq_rel, almemory_order_acquire))
return AL_STOPPED;
return state;
@@ -747,7 +747,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
Source->SourceType = AL_UNDETERMINED;
newlist = NULL;
}
- oldlist = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &Source->queue, newlist);
+ oldlist = ATOMIC_EXCHANGE_PTR_SEQ(&Source->queue, newlist);
WriteUnlock(&Source->queue_lock);
UnlockBuffersRead(device);
@@ -2784,8 +2784,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu
source->SourceType = AL_STREAMING;
BufferList = NULL;
- if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALbufferlistitem*, &source->queue,
- &BufferList, BufferListStart))
+ if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&source->queue, &BufferList,
+ BufferListStart))
{
/* Queue head is not NULL, append to the end of the queue */
while(BufferList->next != NULL)
@@ -2854,7 +2854,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_SEQ(ALbufferlistitem*, &source->queue, OldTail->next);
+ OldHead = ATOMIC_EXCHANGE_PTR_SEQ(&source->queue, OldTail->next);
if(OldTail->next)
{
ALCdevice *device = context->Device;
@@ -3003,7 +3003,7 @@ static void DeinitSource(ALsource *source, ALsizei num_sends)
if(count > 3)
WARN("Freed "SZFMT" Source property objects\n", count);
- BufferList = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &source->queue, NULL);
+ BufferList = ATOMIC_EXCHANGE_PTR_SEQ(&source->queue, NULL);
while(BufferList != NULL)
{
ALbufferlistitem *next = BufferList->next;
@@ -3040,9 +3040,8 @@ static void UpdateSourceProps(ALsource *source, ALsizei num_sends)
struct ALsourceProps *next;
do {
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
- &source->FreeList, &props, next, almemory_order_acq_rel,
- almemory_order_acquire) == 0);
+ } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&source->FreeList, &props, next,
+ almemory_order_acq_rel, almemory_order_acquire) == 0);
}
/* Copy in current property values. */
@@ -3103,7 +3102,7 @@ static void UpdateSourceProps(ALsource *source, ALsizei num_sends)
}
/* Set the new container for updating internal parameters. */
- props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, props, almemory_order_acq_rel);
+ props = ATOMIC_EXCHANGE_PTR(&source->Update, props, almemory_order_acq_rel);
if(props)
{
/* If there was an unused update container, put it back in the
diff --git a/include/atomic.h b/include/atomic.h
index 57609c33..a42cfa4a 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -34,10 +34,10 @@ extern "C" {
#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_EXCHANGE(T, _val, _newval, _MO) atomic_exchange_explicit(_val, _newval, _MO)
-#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _orig, _newval, _MO1, _MO2) \
+#define ATOMIC_EXCHANGE(_val, _newval, _MO) atomic_exchange_explicit(_val, _newval, _MO)
+#define ATOMIC_COMPARE_EXCHANGE_STRONG(_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) \
+#define ATOMIC_COMPARE_EXCHANGE_WEAK(_val, _orig, _newval, _MO1, _MO2) \
atomic_compare_exchange_weak_explicit(_val, _orig, _newval, _MO1, _MO2)
#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) atomic_flag_test_and_set_explicit(_val, _MO)
@@ -77,14 +77,12 @@ enum almemory_order {
#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, _MO) __extension__({ \
- static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
+#define ATOMIC_EXCHANGE(_val, _newval, _MO) __extension__({ \
__asm__ __volatile__("" ::: "memory"); \
__sync_lock_test_and_set(&(_val)->value, (_newval)); \
})
-#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); \
+#define ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, _MO1, _MO2) __extension__({ \
+ __typeof(*(_oldval)) _o = *(_oldval); \
*(_oldval) = __sync_val_compare_and_swap(&(_val)->value, _o, (_newval)); \
*(_oldval) == _o; \
})
@@ -175,20 +173,29 @@ enum almemory_order {
_r; \
})
-#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; \
- if(sizeof(T) == 4) WRAP_XCHG("l", _r, &(_val)->value, (T)(_newval)); \
- else if(sizeof(T) == 8) WRAP_XCHG("q", _r, &(_val)->value, (T)(_newval)); \
+#define ATOMIC_EXCHANGE(_val, _newval, _MO) __extension__({ \
+ __typeof((_val)->value) _r; \
+ if(sizeof((_val)->value) == 4) WRAP_XCHG("l", _r, &(_val)->value, (_newval)); \
+ else if(sizeof((_val)->value) == 8) WRAP_XCHG("q", _r, &(_val)->value, (_newval)); \
_r; \
})
-#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); \
- if(sizeof(T) == 4) WRAP_CMPXCHG("l", *(_oldval), &(_val)->value, _old, (T)(_newval)); \
- else if(sizeof(T) == 8) WRAP_CMPXCHG("q", *(_oldval), &(_val)->value, _old, (T)(_newval)); \
+#define ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, _MO1, _MO2) __extension__({ \
+ __typeof(*(_oldval)) _old = *(_oldval); \
+ if(sizeof((_val)->value) == 4) WRAP_CMPXCHG("l", *(_oldval), &(_val)->value, _old, (_newval)); \
+ else if(sizeof((_val)->value) == 8) WRAP_CMPXCHG("q", *(_oldval), &(_val)->value, _old, (_newval)); \
+ *(_oldval) == _old; \
+})
+
+#define ATOMIC_EXCHANGE_PTR(_val, _newval, _MO) __extension__({ \
+ void *_r; \
+ if(sizeof(void*) == 4) WRAP_XCHG("l", _r, &(_val)->value, (_newval)); \
+ else if(sizeof(void*) == 8) WRAP_XCHG("q", _r, &(_val)->value, (_newval));\
+ _r; \
+})
+#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG(_val, _oldval, _newval, _MO1, _MO2) __extension__({ \
+ void *_old = *(_oldval); \
+ if(sizeof(void*) == 4) WRAP_CMPXCHG("l", *(_oldval), &(_val)->value, _old, (_newval)); \
+ else if(sizeof(void*) == 8) WRAP_CMPXCHG("q", *(_oldval), &(_val)->value, _old, (_newval)); \
*(_oldval) == _old; \
})
@@ -205,14 +212,13 @@ enum almemory_order {
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-/* NOTE: This mess is *extremely* noisy, at least on GCC. It works by wrapping
- * Windows' 32-bit and 64-bit atomic methods, which are then casted to use the
- * given type based on its size (e.g. int and float use 32-bit atomics). This
- * is fine for the swap and compare-and-swap methods, although the add and
- * subtract methods only work properly for integer types.
+/* NOTE: This mess is *extremely* touchy. It lacks quite a bit of safety
+ * checking due to the lack of multi-statement expressions, typeof(), and C99
+ * compound literals. It is incapable of properly exchanging floats, which get
+ * casted to LONG/int, and could cast away potential warnings.
*
- * Despite how noisy it is, it's unfortunately the only way that doesn't rely
- * on C99 (damn MSVC).
+ * Unfortunately, it's the only semi-safe way that doesn't rely on C99 (because
+ * MSVC).
*/
inline LONG AtomicAdd32(volatile LONG *dest, LONG incr)
@@ -240,6 +246,10 @@ inline LONGLONG AtomicSwap64(volatile LONGLONG *dest, LONGLONG newval)
{
return InterlockedExchange64(dest, newval);
}
+inline void *AtomicSwapPtr(void *volatile *dest, void *newval)
+{
+ return InterlockedExchangePointer(dest, newval);
+}
inline bool CompareAndSwap32(volatile LONG *dest, LONG newval, LONG *oldval)
{
@@ -253,10 +263,16 @@ inline bool CompareAndSwap64(volatile LONGLONG *dest, LONGLONG newval, LONGLONG
*oldval = InterlockedCompareExchange64(dest, newval, *oldval);
return old == *oldval;
}
+inline bool CompareAndSwapPtr(void *volatile *dest, void *newval, void **oldval)
+{
+ void *old = *oldval;
+ *oldval = InterlockedCompareExchangePointer(dest, newval, *oldval);
+ return old == *oldval;
+}
#define WRAP_ADDSUB(T, _func, _ptr, _amnt) _func((T volatile*)(_ptr), (_amnt))
-#define WRAP_XCHG(T, _func, _ptr, _newval) ((T(*)(T volatile*,T))_func)((_ptr), (_newval))
-#define WRAP_CMPXCHG(T, _func, _ptr, _newval, _oldval) ((bool(*)(T volatile*,T,T*))_func)((_ptr), (_newval), (_oldval))
+#define WRAP_XCHG(T, _func, _ptr, _newval) _func((T volatile*)(_ptr), (_newval))
+#define WRAP_CMPXCHG(T, _func, _ptr, _newval, _oldval) _func((T volatile*)(_ptr), (_newval), (T*)(_oldval))
enum almemory_order {
@@ -289,13 +305,20 @@ int _al_invalid_atomic_size(); /* not defined */
(sizeof((_val)->value)==8) ? WRAP_ADDSUB(LONGLONG, AtomicSub64, &(_val)->value, (_decr)) : \
_al_invalid_atomic_size())
-#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, _MO1, _MO2) \
- ((sizeof(T)==4) ? WRAP_CMPXCHG(T, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \
- (sizeof(T)==8) ? WRAP_CMPXCHG(T, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \
+#define ATOMIC_EXCHANGE(_val, _newval, _MO) \
+ ((sizeof((_val)->value)==4) ? WRAP_XCHG(LONG, AtomicSwap32, &(_val)->value, (_newval)) : \
+ (sizeof((_val)->value)==8) ? WRAP_XCHG(LONGLONG, AtomicSwap64, &(_val)->value, (_newval)) : \
+ (LONG)_al_invalid_atomic_size())
+#define ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, _MO1, _MO2) \
+ ((sizeof((_val)->value)==4) ? WRAP_CMPXCHG(LONG, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \
+ (sizeof((_val)->value)==8) ? WRAP_CMPXCHG(LONGLONG, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \
+ (bool)_al_invalid_atomic_size())
+
+#define ATOMIC_EXCHANGE_PTR(_val, _newval, _MO) \
+ ((sizeof((_val)->value)==sizeof(void*)) ? AtomicSwapPtr((void*volatile*)&(_val)->value, (_newval)) : \
+ (void*)_al_invalid_atomic_size())
+#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG(_val, _oldval, _newval, _MO1, _MO2)\
+ ((sizeof((_val)->value)==sizeof(void*)) ? CompareAndSwapPtr((void*volatile*)&(_val)->value, (_newval), (void**)(_oldval)) : \
(bool)_al_invalid_atomic_size())
#define ATOMIC_THREAD_FENCE(order) do { \
@@ -320,21 +343,27 @@ int _al_invalid_atomic_size(); /* not defined */
#define ATOMIC_ADD(...) (0)
#define ATOMIC_SUB(...) (0)
-#define ATOMIC_EXCHANGE(T, ...) (0)
-#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, ...) (0)
-#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, ...) (0)
-
-#define ATOMIC_FLAG_TEST_AND_SET(...) (0)
-#define ATOMIC_FLAG_CLEAR(...) ((void)0)
+#define ATOMIC_EXCHANGE(...) (0)
+#define ATOMIC_COMPARE_EXCHANGE_STRONG(...) (0)
#define ATOMIC_THREAD_FENCE(...) ((void)0)
#endif
+/* If no PTR xchg variants are provided, the normal ones can handle it. */
+#ifndef ATOMIC_EXCHANGE_PTR
+#define ATOMIC_EXCHANGE_PTR ATOMIC_EXCHANGE
+#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG ATOMIC_COMPARE_EXCHANGE_STRONG
+#define ATOMIC_COMPARE_EXCHANGE_PTR_WEAK ATOMIC_COMPARE_EXCHANGE_WEAK
+#endif
+
/* If no weak cmpxchg is provided (not all systems will have one), substitute a
* strong cmpxchg. */
#ifndef ATOMIC_COMPARE_EXCHANGE_WEAK
#define ATOMIC_COMPARE_EXCHANGE_WEAK ATOMIC_COMPARE_EXCHANGE_STRONG
#endif
+#ifndef ATOMIC_COMPARE_EXCHANGE_PTR_WEAK
+#define ATOMIC_COMPARE_EXCHANGE_PTR_WEAK ATOMIC_COMPARE_EXCHANGE_PTR_STRONG
+#endif
/* If no ATOMIC_FLAG is defined, simulate one with an atomic int using exchange
* and store ops.
@@ -342,7 +371,7 @@ 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, _MO) ATOMIC_EXCHANGE(int, _val, 1, _MO)
+#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) ATOMIC_EXCHANGE(_val, 1, _MO)
#define ATOMIC_FLAG_CLEAR(_val, _MO) ATOMIC_STORE(_val, 0, _MO)
#endif
@@ -353,11 +382,17 @@ int _al_invalid_atomic_size(); /* not defined */
#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)
+#define ATOMIC_EXCHANGE_SEQ(_val, _newval) ATOMIC_EXCHANGE(_val, _newval, almemory_order_seq_cst)
+#define ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(_val, _oldval, _newval) \
+ ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst)
+#define ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(_val, _oldval, _newval) \
+ ATOMIC_COMPARE_EXCHANGE_WEAK(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst)
+
+#define ATOMIC_EXCHANGE_PTR_SEQ(_val, _newval) ATOMIC_EXCHANGE_PTR(_val, _newval, almemory_order_seq_cst)
+#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(_val, _oldval, _newval) \
+ ATOMIC_COMPARE_EXCHANGE_PTR_STRONG(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst)
+#define ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(_val, _oldval, _newval) \
+ ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst)
typedef unsigned int uint;
@@ -381,7 +416,7 @@ inline uint DecrementRef(RefCount *ptr)
T _first = ATOMIC_LOAD(_head, almemory_order_acquire); \
do { \
ATOMIC_STORE(&(_entry)->next, _first, almemory_order_relaxed); \
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(T, _head, &_first, _entry, \
+ } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(_head, &_first, _entry, \
almemory_order_acq_rel, almemory_order_acquire) == 0); \
} while(0)