Add a helper to wait for the device mix
This commit is contained in:
parent
3e1a2c0f77
commit
accc1ec1c8
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
17
alc/alc.cpp
17
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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user