diff options
author | Chris Robinson <[email protected]> | 2020-03-03 20:32:44 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-03-03 20:32:44 -0800 |
commit | accc1ec1c8bcb241dc4b71b97d8110ff8973d190 (patch) | |
tree | 8871bf211b0e3f7b0089ab7fb1d1347bfbd092c3 | |
parent | 3e1a2c0f77baa81244a436e29db4e4780cdc2105 (diff) |
Add a helper to wait for the device mix
-rw-r--r-- | al/auxeffectslot.cpp | 10 | ||||
-rw-r--r-- | al/source.cpp | 25 | ||||
-rw-r--r-- | alc/alc.cpp | 17 | ||||
-rw-r--r-- | alc/alcmain.h | 9 | ||||
-rw-r--r-- | alc/backends/base.cpp | 3 |
5 files changed, 28 insertions, 36 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index efc75aac..dbd16928 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -117,9 +117,8 @@ void AddActiveEffectSlots(const ALuint *slotids, size_t count, ALCcontext *conte std::uninitialized_fill_n(newarray->end(), newcount, nullptr); curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel); - ALCdevice *device{context->mDevice.get()}; - while((device->MixCount.load(std::memory_order_acquire)&1)) - std::this_thread::yield(); + context->mDevice->waitForMix(); + al::destroy_n(curarray->end(), curarray->size()); delete curarray; } @@ -155,9 +154,8 @@ void RemoveActiveEffectSlots(const ALuint *slotids, size_t count, ALCcontext *co std::uninitialized_fill_n(newarray->end(), newsize, nullptr); curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel); - ALCdevice *device{context->mDevice.get()}; - while((device->MixCount.load(std::memory_order_acquire)&1)) - std::this_thread::yield(); + context->mDevice->waitForMix(); + al::destroy_n(curarray->end(), curarray->size()); delete curarray; } diff --git a/al/source.cpp b/al/source.cpp index b0613068..39ae8b8e 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -188,10 +188,9 @@ int64_t GetSourceSampleOffset(ALsource *Source, ALCcontext *context, nanoseconds do { Current = nullptr; readPos = 0; - while(((refcount=device->MixCount.load(std::memory_order_acquire))&1)) - std::this_thread::yield(); - *clocktime = GetDeviceClockTime(device); + refcount = device->waitForMix(); + *clocktime = GetDeviceClockTime(device); voice = GetSourceVoice(Source, context); if(voice) { @@ -234,10 +233,9 @@ ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, nanoseconds * do { Current = nullptr; readPos = 0; - while(((refcount=device->MixCount.load(std::memory_order_acquire))&1)) - std::this_thread::yield(); - *clocktime = GetDeviceClockTime(device); + refcount = device->waitForMix(); + *clocktime = GetDeviceClockTime(device); voice = GetSourceVoice(Source, context); if(voice) { @@ -292,8 +290,8 @@ ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context) do { Current = nullptr; readPos = readPosFrac = 0; - while(((refcount=device->MixCount.load(std::memory_order_acquire))&1)) - std::this_thread::yield(); + refcount = device->waitForMix(); + voice = GetSourceVoice(Source, context); if(voice) { @@ -578,9 +576,7 @@ void SendVoiceChanges(ALCcontext *ctx, VoiceChange *tail) oldhead->mNext.store(tail, std::memory_order_release); const bool connected{device->Connected.load(std::memory_order_acquire)}; - ALuint refcount; - while(((refcount=device->MixCount.load(std::memory_order_acquire))&1)) - std::this_thread::yield(); + device->waitForMix(); if UNLIKELY(!connected) { /* If the device is disconnected, just ignore all pending changes. */ @@ -677,9 +673,7 @@ bool SetVoiceOffset(ALvoice *oldvoice, const VoicePos &vpos, ALsource *source, A return true; /* Otherwise, wait for any current mix to finish and check one last time. */ - ALuint refcount; - while((refcount=device->MixCount.load(std::memory_order_acquire))&1) - std::this_thread::yield(); + device->waitForMix(); if(!newvoice->mPendingChange.exchange(false, std::memory_order_acq_rel)) return true; /* The change-over failed because the old voice stopped before the new @@ -1341,8 +1335,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a * to ensure it isn't currently looping back or reaching the * end. */ - while((device->MixCount.load(std::memory_order_acquire)&1)) - std::this_thread::yield(); + device->waitForMix(); } } return true; diff --git a/alc/alc.cpp b/alc/alc.cpp index e03dc2f6..0962276d 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1679,9 +1679,7 @@ void ALCcontext::allocVoices(size_t addcount) if(auto *oldvoices = mVoices.exchange(newarray.release(), std::memory_order_acq_rel)) { - ALuint refcount; - while((refcount=mDevice->MixCount.load(std::memory_order_acquire))&1) - std::this_thread::yield(); + mDevice->waitForMix(); delete oldvoices; } } @@ -2675,8 +2673,7 @@ bool ALCcontext::deinit() mDevice->mContexts.store(newarray); if(oldarray != &EmptyContextArray) { - while((mDevice->MixCount.load(std::memory_order_acquire)&1)) - std::this_thread::yield(); + mDevice->waitForMix(); delete oldarray; } @@ -3321,8 +3318,7 @@ START_API_FUNC ALuint samplecount; ALuint refcount; do { - while(((refcount=ReadRef(dev->MixCount))&1) != 0) - std::this_thread::yield(); + refcount = dev->waitForMix(); basecount = dev->ClockBase; samplecount = dev->SamplesDone; } while(refcount != ReadRef(dev->MixCount)); @@ -3516,8 +3512,7 @@ START_API_FUNC dev->mContexts.store(newarray.release()); if(oldarray != &EmptyContextArray) { - while((dev->MixCount.load(std::memory_order_acquire)&1)) - std::this_thread::yield(); + dev->waitForMix(); delete oldarray; } } @@ -4349,9 +4344,7 @@ START_API_FUNC if(!dev->Connected.load(std::memory_order_relaxed)) { /* Make sure disconnection is finished before continuing on. */ - ALuint refcount; - while(((refcount=dev->MixCount.load(std::memory_order_acquire))&1)) - std::this_thread::yield(); + dev->waitForMix(); for(ALCcontext *ctx : *dev->mContexts.load(std::memory_order_acquire)) { diff --git a/alc/alcmain.h b/alc/alcmain.h index 071e43f5..1560b831 100644 --- a/alc/alcmain.h +++ b/alc/alcmain.h @@ -10,6 +10,7 @@ #include <memory> #include <mutex> #include <string> +#include <thread> #include <utility> #include "AL/al.h" @@ -356,6 +357,14 @@ struct ALCdevice : public al::intrusive_ref<ALCdevice> { ALuint channelsFromFmt() const noexcept { return ChannelsFromDevFmt(FmtChans, mAmbiOrder); } ALuint frameSizeFromFmt() const noexcept { return bytesFromFmt() * channelsFromFmt(); } + ALuint waitForMix() const noexcept + { + ALuint refcount; + while((refcount=MixCount.load(std::memory_order_acquire))&1) + std::this_thread::yield(); + return refcount; + } + void ProcessHrtf(const size_t SamplesToDo); void ProcessAmbiDec(const size_t SamplesToDo); void ProcessUhj(const size_t SamplesToDo); diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp index 25531cf5..f79f2063 100644 --- a/alc/backends/base.cpp +++ b/alc/backends/base.cpp @@ -44,8 +44,7 @@ ClockLatency BackendBase::getClockLatency() ALuint refcount; do { - while(((refcount=ReadRef(mDevice->MixCount))&1) != 0) - std::this_thread::yield(); + refcount = mDevice->waitForMix(); ret.ClockTime = GetDeviceClockTime(mDevice); std::atomic_thread_fence(std::memory_order_acquire); } while(refcount != ReadRef(mDevice->MixCount)); |