aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h2
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/alAuxEffectSlot.c67
3 files changed, 34 insertions, 37 deletions
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h
index 85d730f8..a9b50387 100644
--- a/OpenAL32/Include/alAuxEffectSlot.h
+++ b/OpenAL32/Include/alAuxEffectSlot.h
@@ -129,6 +129,8 @@ typedef struct ALeffectslot {
* first-order device output (FOAOut).
*/
alignas(16) ALfloat WetBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE];
+
+ ATOMIC(struct ALeffectslot*) next;
} ALeffectslot;
inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id)
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 50162b0e..d7b54310 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -711,7 +711,7 @@ struct ALCcontext_struct {
ALsizei VoiceCount;
ALsizei MaxVoices;
- VECTOR(struct ALeffectslot*) ActiveAuxSlots;
+ ATOMIC(struct ALeffectslot*) ActiveAuxSlotList;
ALCdevice *Device;
const ALCchar *ExtensionList;
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index c37ecd58..8da7aeb2 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -38,8 +38,8 @@
extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id);
extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id);
-static ALenum AddEffectSlotArray(ALCcontext *Context, ALeffectslot **start, ALsizei count);
-static void RemoveEffectSlotArray(ALCcontext *Context, const ALeffectslot *slot);
+static void AddEffectSlotList(ALCcontext *Context, ALeffectslot *first, ALeffectslot *last);
+static void RemoveEffectSlotList(ALCcontext *Context, const ALeffectslot *slot);
static UIntMap EffectStateFactoryMap;
@@ -55,20 +55,17 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type)
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
{
ALCcontext *context;
- VECTOR(ALeffectslot*) slotvec;
+ ALeffectslot *first, *last;
ALsizei cur;
ALenum err;
context = GetContextRef();
if(!context) return;
- VECTOR_INIT(slotvec);
-
if(!(n >= 0))
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- if(!VECTOR_RESERVE(slotvec, n))
- SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
+ first = last = NULL;
for(cur = 0;cur < n;cur++)
{
ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot));
@@ -95,20 +92,15 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
aluInitEffectPanning(slot);
- VECTOR_PUSH_BACK(slotvec, slot);
+ if(!first) first = slot;
+ if(last) ATOMIC_STORE(&last->next, slot);
+ last = slot;
effectslots[cur] = slot->id;
}
- err = AddEffectSlotArray(context, VECTOR_BEGIN(slotvec), n);
- if(err != AL_NO_ERROR)
- {
- alDeleteAuxiliaryEffectSlots(cur, effectslots);
- SET_ERROR_AND_GOTO(context, err, done);
- }
+ AddEffectSlotList(context, first, last);
done:
- VECTOR_DEINIT(slotvec);
-
ALCcontext_DecRef(context);
}
@@ -138,7 +130,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *
continue;
FreeThunkEntry(slot->id);
- RemoveEffectSlotArray(context, slot);
+ RemoveEffectSlotList(context, slot);
DeinitEffectSlot(slot);
memset(slot, 0, sizeof(*slot));
@@ -399,32 +391,33 @@ done:
}
-static ALenum AddEffectSlotArray(ALCcontext *context, ALeffectslot **start, ALsizei count)
+static void AddEffectSlotList(ALCcontext *context, ALeffectslot *start, ALeffectslot *last)
{
- ALenum err = AL_NO_ERROR;
-
- LockContext(context);
- if(!VECTOR_INSERT(context->ActiveAuxSlots, VECTOR_END(context->ActiveAuxSlots), start, start+count))
- err = AL_OUT_OF_MEMORY;
- UnlockContext(context);
-
- return err;
+ ALeffectslot *root = ATOMIC_LOAD(&context->ActiveAuxSlotList);
+ do {
+ ATOMIC_STORE(&last->next, root, almemory_order_relaxed);
+ } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALeffectslot*, &context->ActiveAuxSlotList,
+ &root, start));
}
-static void RemoveEffectSlotArray(ALCcontext *context, const ALeffectslot *slot)
+static void RemoveEffectSlotList(ALCcontext *context, const ALeffectslot *slot)
{
- ALeffectslot **iter;
+ ALCdevice *device = context->Device;
+ const ALeffectslot *root, *next;
- LockContext(context);
-#define MATCH_SLOT(_i) (slot == *(_i))
- VECTOR_FIND_IF(iter, ALeffectslot*, context->ActiveAuxSlots, MATCH_SLOT);
- if(iter != VECTOR_END(context->ActiveAuxSlots))
+ root = slot;
+ next = ATOMIC_LOAD(&slot->next);
+ if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next))
{
- *iter = VECTOR_BACK(context->ActiveAuxSlots);
- VECTOR_POP_BACK(context->ActiveAuxSlots);
+ const ALeffectslot *cur;
+ do {
+ cur = root;
+ root = slot;
+ } while(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &cur->next, &root, next));
}
-#undef MATCH_SLOT
- UnlockContext(context);
+ /* Wait for any mix that may be using these effect slots to finish. */
+ while((ReadRef(&device->MixCount)&1) != 0)
+ althrd_yield();
}
@@ -539,6 +532,8 @@ ALenum InitEffectSlot(ALeffectslot *slot)
slot->Params.DecayTime = 0.0f;
slot->Params.AirAbsorptionGainHF = 1.0f;
+ ATOMIC_INIT(&slot->next, NULL);
+
return AL_NO_ERROR;
}