diff options
-rw-r--r-- | Alc/ALu.c | 41 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 6 | ||||
-rw-r--r-- | OpenAL32/alListener.c | 6 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 7 | ||||
-rw-r--r-- | include/atomic.h | 12 |
5 files changed, 18 insertions, 54 deletions
@@ -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 |