aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2011-08-29 00:50:55 -0700
committerChris Robinson <[email protected]>2011-08-29 00:50:55 -0700
commit58078e2c1eb2a3778462c1d0632b0a2c85fe82ec (patch)
tree434158738f276fd2ef6f1c855fa895044a348822
parent01503f8a7bd99136445008eba5bed5af483a7aea (diff)
Use atomic exchanges when checking for updates to objects' internal parameters
-rw-r--r--Alc/ALu.c20
-rw-r--r--OpenAL32/Include/alMain.h35
-rw-r--r--OpenAL32/alState.c11
3 files changed, 44 insertions, 22 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index d7eba154..b11a1c3a 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -978,14 +978,11 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ctx = device->ContextList;
while(ctx)
{
- ALboolean DeferUpdates = ctx->DeferUpdates;
- ALboolean UpdateSources = AL_FALSE;
+ ALenum DeferUpdates = ctx->DeferUpdates;
+ ALenum UpdateSources = AL_FALSE;
if(!DeferUpdates)
- {
- UpdateSources = ctx->UpdateSources;
- ctx->UpdateSources = AL_FALSE;
- }
+ UpdateSources = Exchange_ALenum(&ctx->UpdateSources, AL_FALSE);
src = ctx->ActiveSources;
src_end = src + ctx->ActiveSourceCount;
@@ -998,11 +995,9 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
continue;
}
- if(!DeferUpdates && ((*src)->NeedsUpdate || UpdateSources))
- {
- (*src)->NeedsUpdate = AL_FALSE;
+ if(!DeferUpdates && (Exchange_ALenum(&(*src)->NeedsUpdate, AL_FALSE) ||
+ UpdateSources))
ALsource_Update(*src, ctx);
- }
MixSource(*src, device, SamplesToDo);
src++;
@@ -1024,11 +1019,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALEffectSlot->PendingClicks[i] = 0.0f;
}
- if(!DeferUpdates && ALEffectSlot->NeedsUpdate)
- {
- ALEffectSlot->NeedsUpdate = AL_FALSE;
+ if(!DeferUpdates && Exchange_ALenum(&ALEffectSlot->NeedsUpdate, AL_FALSE))
ALEffect_Update(ALEffectSlot->EffectState, ctx, ALEffectSlot);
- }
ALEffect_Process(ALEffectSlot->EffectState, ALEffectSlot,
SamplesToDo, ALEffectSlot->WetBuffer,
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 641baf7c..fa11a3d8 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -249,6 +249,12 @@ static __inline RefCount IncrementRef(volatile RefCount *ptr)
static __inline RefCount DecrementRef(volatile RefCount *ptr)
{ return __sync_sub_and_fetch(ptr, 1); }
+#define DECL_TEMPLATE(T) \
+static __inline T Exchange_##T(volatile T *ptr, T newval) \
+{ \
+ return __sync_lock_test_and_set(ptr, newval); \
+}
+
#elif defined(_WIN32)
typedef LONG RefCount;
@@ -257,6 +263,16 @@ static __inline RefCount IncrementRef(volatile RefCount *ptr)
static __inline RefCount DecrementRef(volatile RefCount *ptr)
{ return InterlockedDecrement(ptr); }
+#define DECL_TEMPLATE(T) \
+static __inline T Exchange_##T(volatile T *ptr, T newval) \
+{ \
+ union { \
+ volatile T *t; \
+ volatile LONG *l; \
+ } u = { ptr }; \
+ return InterlockedExchange(u.l, newval); \
+}
+
#elif defined(__APPLE__)
#include <libkern/OSAtomic.h>
@@ -267,10 +283,29 @@ static __inline RefCount IncrementRef(volatile RefCount *ptr)
static __inline RefCount DecrementRef(volatile RefCount *ptr)
{ return OSAtomicDecrement32Barrier(ptr); }
+#define DECL_TEMPLATE(T) \
+static __inline T Exchange_##T(volatile T *ptr, T newval) \
+{ \
+ union { \
+ volatile T *t; \
+ volatile int32_t *l; \
+ } u = { ptr }; \
+ /* Really? No regular old atomic swap? */ \
+ T oldval; \
+ do { \
+ oldval = *u.i; \
+ } while(!OSAtomicCompareAndSwap32Barrier(oldval, newval, u.i)); \
+ return oldval; \
+}
+
#else
#error "No atomic functions available on this platform!"
#endif
+DECL_TEMPLATE(ALenum)
+
+#undef DECL_TEMPLATE
+
#include "alListener.h"
#include "alu.h"
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index 8e4c4671..7e73f407 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -604,22 +604,17 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
continue;
}
- if((*src)->NeedsUpdate || UpdateSources)
- {
- (*src)->NeedsUpdate = AL_FALSE;
+ if(Exchange_ALenum(&(*src)->NeedsUpdate, AL_FALSE) || UpdateSources)
ALsource_Update(*src, Context);
- }
+
src++;
}
for(e = 0;e < Context->EffectSlotMap.size;e++)
{
ALEffectSlot = Context->EffectSlotMap.array[e].value;
- if(ALEffectSlot->NeedsUpdate)
- {
- ALEffectSlot->NeedsUpdate = AL_FALSE;
+ if(Exchange_ALenum(&ALEffectSlot->NeedsUpdate, AL_FALSE))
ALEffect_Update(ALEffectSlot->EffectState, Context, ALEffectSlot);
- }
}
}