aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-03-03 20:32:44 -0800
committerChris Robinson <[email protected]>2020-03-03 20:32:44 -0800
commitaccc1ec1c8bcb241dc4b71b97d8110ff8973d190 (patch)
tree8871bf211b0e3f7b0089ab7fb1d1347bfbd092c3
parent3e1a2c0f77baa81244a436e29db4e4780cdc2105 (diff)
Add a helper to wait for the device mix
-rw-r--r--al/auxeffectslot.cpp10
-rw-r--r--al/source.cpp25
-rw-r--r--alc/alc.cpp17
-rw-r--r--alc/alcmain.h9
-rw-r--r--alc/backends/base.cpp3
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));