aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALu.c41
-rw-r--r--OpenAL32/alAuxEffectSlot.c6
-rw-r--r--OpenAL32/alListener.c6
-rw-r--r--OpenAL32/alSource.c7
-rw-r--r--include/atomic.h12
5 files changed, 18 insertions, 54 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index db032057..dc979522 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -239,7 +239,6 @@ static ALboolean CalcListenerParams(ALCcontext *Context)
{
ALlistener *Listener = Context->Listener;
ALfloat N[3], V[3], U[3], P[3];
- struct ALlistenerProps *first;
struct ALlistenerProps *props;
aluVector vel;
@@ -288,24 +287,12 @@ static ALboolean CalcListenerParams(ALCcontext *Context)
Listener->Params.SourceDistanceModel = ATOMIC_LOAD(&props->SourceDistanceModel, almemory_order_relaxed);
Listener->Params.DistanceModel = ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed);
- /* WARNING: A livelock is theoretically possible if another thread keeps
- * changing the freelist head without giving this a chance to actually swap
- * in the old container (practically impossible with this little code,
- * but...).
- */
- first = ATOMIC_LOAD(&Listener->FreeList, almemory_order_acquire);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*,
- &Listener->FreeList, &first, props, almemory_order_acq_rel,
- almemory_order_acquire) == 0);
-
+ ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props);
return AL_TRUE;
}
static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
{
- struct ALeffectslotProps *first;
struct ALeffectslotProps *props;
ALeffectState *state;
@@ -337,18 +324,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
V(state,update)(device, slot, &props->Props);
- /* WARNING: A livelock is theoretically possible if another thread keeps
- * changing the freelist head without giving this a chance to actually swap
- * in the old container (practically impossible with this little code,
- * but...).
- */
- first = ATOMIC_LOAD(&slot->FreeList, almemory_order_acquire);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*,
- &slot->FreeList, &first, props, almemory_order_acq_rel,
- almemory_order_acquire) == 0);
-
+ ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props);
return AL_TRUE;
}
@@ -1301,7 +1277,6 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc
{
ALsource *source = voice->Source;
const ALbufferlistitem *BufferListItem;
- struct ALsourceProps *first;
struct ALsourceProps *props;
props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel);
@@ -1311,17 +1286,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc
{
voice->Props = *props;
- /* WARNING: A livelock is theoretically possible if another thread
- * keeps changing the freelist head without giving this a chance to
- * actually swap in the old container (practically impossible with this
- * little code, but...).
- */
- first = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
- &source->FreeList, &first, props, almemory_order_acq_rel,
- almemory_order_acquire) == 0);
+ ATOMIC_REPLACE_HEAD(struct ALsourceProps*, &source->FreeList, props);
}
BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index a7bc0f32..e6b4ff68 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -671,11 +671,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot)
/* If there was an unused update container, put it back in the
* freelist.
*/
- struct ALeffectslotProps *first = ATOMIC_LOAD_SEQ(&slot->FreeList);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALeffectslotProps*,
- &slot->FreeList, &first, props) == 0);
+ ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props);
}
if(oldstate)
diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c
index f05c20d1..9c237e99 100644
--- a/OpenAL32/alListener.c
+++ b/OpenAL32/alListener.c
@@ -506,10 +506,6 @@ void UpdateListenerProps(ALCcontext *context)
/* If there was an unused update container, put it back in the
* freelist.
*/
- struct ALlistenerProps *first = ATOMIC_LOAD_SEQ(&listener->FreeList);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALlistenerProps*,
- &listener->FreeList, &first, props) == 0);
+ ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &listener->FreeList, props);
}
}
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 9f60c545..e3d3cf1b 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -2913,12 +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_SEQ(&source->FreeList);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
- &source->FreeList, &first, props, almemory_order_acq_rel,
- almemory_order_acquire) == 0);
+ ATOMIC_REPLACE_HEAD(struct ALsourceProps*, &source->FreeList, props);
}
}
diff --git a/include/atomic.h b/include/atomic.h
index 4783defe..57609c33 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -373,6 +373,18 @@ inline uint DecrementRef(RefCount *ptr)
{ return ATOMIC_SUB_SEQ(ptr, 1)-1; }
+/* WARNING: A livelock is theoretically possible if another thread keeps
+ * changing the head without giving this a chance to actually swap in the new
+ * one (practically impossible with this little code, but...).
+ */
+#define ATOMIC_REPLACE_HEAD(T, _head, _entry) do { \
+ 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, \
+ almemory_order_acq_rel, almemory_order_acquire) == 0); \
+} while(0)
+
#ifdef __cplusplus
}
#endif