From f94fa5d5cfb78ab5438a53b2ad17f033660103c9 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Fri, 14 Apr 2017 17:47:55 -0700
Subject: Use separate atomic macros for pointers

---
 Alc/ALc.c                  |  36 ++++++------
 Alc/ALu.c                  |  12 ++--
 Alc/backends/opensl.c      |   4 +-
 Alc/backends/oss.c         |   4 +-
 Alc/backends/solaris.c     |   2 +-
 Alc/helpers.c              |   4 +-
 OpenAL32/alAuxEffectSlot.c |  18 +++---
 OpenAL32/alError.c         |   4 +-
 OpenAL32/alListener.c      |   7 +--
 OpenAL32/alSource.c        |  19 +++----
 include/atomic.h           | 133 ++++++++++++++++++++++++++++-----------------
 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)
 
-- 
cgit v1.2.3