diff options
Diffstat (limited to 'alc')
-rw-r--r-- | alc/alc.cpp | 70 | ||||
-rw-r--r-- | alc/alcmain.h | 5 | ||||
-rw-r--r-- | alc/alcontext.h | 9 | ||||
-rw-r--r-- | alc/alu.cpp | 24 | ||||
-rw-r--r-- | alc/backends/base.cpp | 4 | ||||
-rw-r--r-- | alc/effects/base.h | 9 | ||||
-rw-r--r-- | alc/hrtf.cpp | 8 |
7 files changed, 43 insertions, 86 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp index 240aca6d..73723f26 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -79,6 +79,7 @@ #include "fpu_modes.h" #include "hrtf.h" #include "inprogext.h" +#include "intrusive_ptr.h" #include "logging.h" #include "mastering.h" #include "opthelpers.h" @@ -832,9 +833,9 @@ std::atomic<ALCenum> LastNullDeviceError{ALC_NO_ERROR}; /* Thread-local current context */ void ReleaseThreadCtx(ALCcontext *context) { - auto ref = DecrementRef(&context->mRef); - TRACEREF("ALCcontext %p decreasing refcount to %u\n", context, ref); - ERR("Context %p current for thread being destroyed, possible leak!\n", context); + const bool result{context->releaseIfNoDelete()}; + ERR("Context %p current for thread being destroyed%s!\n", context, + result ? "" : ", leak detected"); } std::atomic<void(*)(ALCcontext*)> ThreadCtxProc{ReleaseThreadCtx}; @@ -907,19 +908,6 @@ constexpr ALCint alcEFXMinorVersion = 0; al::FlexArray<ALCcontext*> EmptyContextArray{0u}; -void ALCdevice_IncRef(ALCdevice *device) -{ - auto ref = IncrementRef(&device->ref); - TRACEREF("ALCdevice %p increasing refcount to %u\n", device, ref); -} - -void ALCdevice_DecRef(ALCdevice *device) -{ - auto ref = DecrementRef(&device->ref); - TRACEREF("ALCdevice %p decreasing refcount to %u\n", device, ref); - if(UNLIKELY(ref == 0)) delete device; -} - /* Simple RAII device reference. Takes the reference of the provided ALCdevice, * and decrements it when leaving scope. Movable (transfer reference) but not * copyable (no new references). @@ -930,7 +918,7 @@ class DeviceRef { void reset() noexcept { if(mDev) - ALCdevice_DecRef(mDev); + mDev->release(); mDev = nullptr; } @@ -1658,10 +1646,10 @@ static std::unique_ptr<Compressor> CreateDeviceLimiter(const ALCdevice *device, */ static inline void UpdateClockBase(ALCdevice *device) { - IncrementRef(&device->MixCount); + IncrementRef(device->MixCount); device->ClockBase += nanoseconds{seconds{device->SamplesDone}} / device->Frequency; device->SamplesDone = 0; - IncrementRef(&device->MixCount); + IncrementRef(device->MixCount); } /* UpdateDeviceParams @@ -2205,7 +2193,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) for(s = device->NumAuxSends;s < old_sends;s++) { if(source->Send[s].Slot) - DecrementRef(&source->Send[s].Slot->ref); + DecrementRef(source->Send[s].Slot->ref); source->Send[s].Slot = nullptr; } source->Send.resize(device->NumAuxSends); @@ -2360,7 +2348,7 @@ static DeviceRef VerifyDevice(ALCdevice *device) auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device); if(iter != DeviceList.cend() && *iter == device) { - ALCdevice_IncRef(iter->get()); + (*iter)->add_ref(); return DeviceRef{iter->get()}; } return DeviceRef{}; @@ -2459,7 +2447,7 @@ ALCcontext::~ALCcontext() while(eprops) { ALeffectslotProps *next{eprops->next.load(std::memory_order_relaxed)}; - if(eprops->State) eprops->State->DecRef(); + if(eprops->State) eprops->State->release(); al_free(eprops); eprops = next; ++count; @@ -2528,7 +2516,7 @@ ALCcontext::~ALCcontext() mAsyncEvents->readAdvance(count); } - ALCdevice_DecRef(mDevice); + mDevice->release(); } /* ReleaseContext @@ -2543,12 +2531,12 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device) { WARN("%p released while current on thread\n", context); LocalContext.set(nullptr); - context->decRef(); + context->release(); } ALCcontext *origctx{context}; if(GlobalContext.compare_exchange_strong(origctx, nullptr)) - context->decRef(); + context->release(); bool ret{}; { @@ -2594,18 +2582,6 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device) return ret; } -static void ALCcontext_IncRef(ALCcontext *context) -{ - auto ref = IncrementRef(&context->mRef); - TRACEREF("ALCcontext %p increasing refcount to %u\n", context, ref); -} - -void ALCcontext::decRef() noexcept -{ - auto ref = DecrementRef(&mRef); - TRACEREF("ALCcontext %p decreasing refcount to %u\n", this, ref); - if(UNLIKELY(ref == 0)) delete this; -} /* VerifyContext * @@ -2617,7 +2593,7 @@ static ContextRef VerifyContext(ALCcontext *context) auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context); if(iter != ContextList.cend() && *iter == context) { - ALCcontext_IncRef(iter->get()); + (*iter)->add_ref(); return ContextRef{iter->get()}; } return ContextRef{}; @@ -2632,12 +2608,12 @@ ContextRef GetContextRef(void) { ALCcontext *context{LocalContext.get()}; if(context) - ALCcontext_IncRef(context); + context->add_ref(); else { std::lock_guard<std::recursive_mutex> _{ListLock}; context = GlobalContext.load(std::memory_order_acquire); - if(context) ALCcontext_IncRef(context); + if(context) context->add_ref(); } return ContextRef{context}; } @@ -3278,11 +3254,11 @@ START_API_FUNC ALuint samplecount; ALuint refcount; do { - while(((refcount=ReadRef(&dev->MixCount))&1) != 0) + while(((refcount=ReadRef(dev->MixCount))&1) != 0) std::this_thread::yield(); basecount = dev->ClockBase; samplecount = dev->SamplesDone; - } while(refcount != ReadRef(&dev->MixCount)); + } while(refcount != ReadRef(dev->MixCount)); basecount += nanoseconds{seconds{samplecount}} / dev->Frequency; *values = basecount.count(); } @@ -3426,7 +3402,7 @@ START_API_FUNC dev->LastError.store(ALC_NO_ERROR); ContextRef context{new ALCcontext{dev.get()}}; - ALCdevice_IncRef(context->mDevice); + dev->add_ref(); ALCenum err{UpdateDeviceParams(dev.get(), attrList)}; if(err != ALC_NO_ERROR) @@ -3502,7 +3478,7 @@ START_API_FUNC { std::lock_guard<std::recursive_mutex> _{ListLock}; auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context.get()); - ALCcontext_IncRef(context.get()); + context->add_ref(); ContextList.insert(iter, ContextRef{context.get()}); } @@ -3850,7 +3826,7 @@ START_API_FUNC { std::lock_guard<std::recursive_mutex> _{ListLock}; auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get()); - ALCdevice_IncRef(device.get()); + device->add_ref(); DeviceList.insert(iter, DeviceRef{device.get()}); } @@ -3976,7 +3952,7 @@ START_API_FUNC { std::lock_guard<std::recursive_mutex> _{ListLock}; auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get()); - ALCdevice_IncRef(device.get()); + device->add_ref(); DeviceList.insert(iter, DeviceRef{device.get()}); } @@ -4145,7 +4121,7 @@ START_API_FUNC { std::lock_guard<std::recursive_mutex> _{ListLock}; auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get()); - ALCdevice_IncRef(device.get()); + device->add_ref(); DeviceList.insert(iter, DeviceRef{device.get()}); } diff --git a/alc/alcmain.h b/alc/alcmain.h index f69dc755..5b4e4a2b 100644 --- a/alc/alcmain.h +++ b/alc/alcmain.h @@ -24,6 +24,7 @@ #include "atomic.h" #include "hrtf.h" #include "inprogext.h" +#include "intrusive_ptr.h" #include "vector.h" class BFormatDec; @@ -310,9 +311,7 @@ enum { DeviceFlagsCount }; -struct ALCdevice { - RefCount ref{1u}; - +struct ALCdevice : public al::intrusive_ref<ALCdevice> { std::atomic<bool> Connected{true}; const DeviceType Type{}; diff --git a/alc/alcontext.h b/alc/alcontext.h index 43b9c08f..53da10dc 100644 --- a/alc/alcontext.h +++ b/alc/alcontext.h @@ -18,6 +18,7 @@ #include "alu.h" #include "atomic.h" #include "inprogext.h" +#include "intrusive_ptr.h" #include "logging.h" #include "threads.h" #include "vector.h" @@ -84,9 +85,7 @@ struct EffectSlotSubList { { std::swap(FreeMask, rhs.FreeMask); std::swap(EffectSlots, rhs.EffectSlots); return *this; } }; -struct ALCcontext { - RefCount mRef{1u}; - +struct ALCcontext : public al::intrusive_ref<ALCcontext> { al::vector<SourceSubList> mSourceList; ALuint mNumSources{0}; std::mutex mSourceLock; @@ -156,8 +155,6 @@ struct ALCcontext { ALCcontext& operator=(const ALCcontext&) = delete; ~ALCcontext(); - void decRef() noexcept; - void allocVoices(size_t num_voices); /** @@ -194,7 +191,7 @@ class ContextRef { void reset() noexcept { if(mCtx) - mCtx->decRef(); + mCtx->release(); mCtx = nullptr; } diff --git a/alc/alu.cpp b/alc/alu.cpp index 2469d08d..8d627b97 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -373,20 +373,10 @@ bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force) EffectState *oldstate{slot->Params.mEffectState}; slot->Params.mEffectState = state; - /* Manually decrement the old effect state's refcount if it's greater - * than 1. We need to be a bit clever here to avoid the refcount - * reaching 0 since it can't be deleted in the mixer. + /* Only decrement the old state if it won't get deleted, since we can't + * be deleting/freeing anything in the mixer. */ - ALuint oldval{oldstate->mRef.load(std::memory_order_acquire)}; - while(oldval > 1 && !oldstate->mRef.compare_exchange_weak(oldval, oldval-1, - std::memory_order_acq_rel, std::memory_order_acquire)) - { - /* oldval was updated with the current value on failure, so just - * try again. - */ - } - - if(oldval < 2) + if(!oldstate->releaseIfNoDelete()) { /* Otherwise, if it would be deleted, send it off with a release * event. @@ -1355,7 +1345,7 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force) void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray *slots) { - IncrementRef(&ctx->mUpdateCount); + IncrementRef(ctx->mUpdateCount); if(LIKELY(!ctx->mHoldUpdates.load(std::memory_order_acquire))) { bool cforce{CalcContextParams(ctx)}; @@ -1374,7 +1364,7 @@ void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray *slots) } ); } - IncrementRef(&ctx->mUpdateCount); + IncrementRef(ctx->mUpdateCount); } void ProcessContext(ALCcontext *ctx, const ALsizei SamplesToDo) @@ -1676,7 +1666,7 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples) ); /* Increment the mix count at the start (lsb should now be 1). */ - IncrementRef(&device->MixCount); + IncrementRef(device->MixCount); /* For each context on this device, process and mix its sources and * effects. @@ -1694,7 +1684,7 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples) device->SamplesDone %= device->Frequency; /* Increment the mix count at the end (lsb should now be 0). */ - IncrementRef(&device->MixCount); + IncrementRef(device->MixCount); /* Apply any needed post-process for finalizing the Dry mix to the * RealOut (Ambisonic decode, UHJ encode, etc). diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp index 78b9196e..095990b7 100644 --- a/alc/backends/base.cpp +++ b/alc/backends/base.cpp @@ -43,11 +43,11 @@ ClockLatency BackendBase::getClockLatency() ALuint refcount; do { - while(((refcount=mDevice->MixCount.load(std::memory_order_acquire))&1)) + while(((refcount=ReadRef(mDevice->MixCount))&1) != 0) std::this_thread::yield(); ret.ClockTime = GetDeviceClockTime(mDevice); std::atomic_thread_fence(std::memory_order_acquire); - } while(refcount != mDevice->MixCount.load(std::memory_order_relaxed)); + } while(refcount != ReadRef(mDevice->MixCount)); /* NOTE: The device will generally have about all but one periods filled at * any given time during playback. Without a more accurate measurement from diff --git a/alc/effects/base.h b/alc/effects/base.h index 4f48de22..89a9e8e4 100644 --- a/alc/effects/base.h +++ b/alc/effects/base.h @@ -5,7 +5,7 @@ #include "almalloc.h" #include "alspan.h" #include "atomic.h" - +#include "intrusive_ptr.h" struct ALeffectslot; @@ -149,9 +149,7 @@ struct EffectTarget { RealMixParams *RealOut; }; -struct EffectState { - RefCount mRef{1u}; - +struct EffectState : public al::intrusive_ref<EffectState> { al::span<FloatBufferLine> mOutTarget; @@ -160,9 +158,6 @@ struct EffectState { virtual ALboolean deviceUpdate(const ALCdevice *device) = 0; virtual void update(const ALCcontext *context, const ALeffectslot *slot, const EffectProps *props, const EffectTarget target) = 0; virtual void process(const ALsizei samplesToDo, const FloatBufferLine *RESTRICT samplesIn, const ALsizei numInput, const al::span<FloatBufferLine> samplesOut) = 0; - - void IncRef() noexcept; - void DecRef() noexcept; }; diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp index 124707c5..a8b56019 100644 --- a/alc/hrtf.cpp +++ b/alc/hrtf.cpp @@ -484,7 +484,7 @@ std::unique_ptr<HrtfEntry> CreateHrtfStore(ALuint rate, ALsizei irSize, const AL ERR("Out of memory allocating storage for %s.\n", filename); else { - InitRef(&Hrtf->ref, 1u); + InitRef(Hrtf->ref, 1u); Hrtf->sampleRate = rate; Hrtf->irSize = irSize; Hrtf->fdCount = fdCount; @@ -1373,13 +1373,13 @@ HrtfEntry *GetLoadedHrtf(HrtfHandle *handle) void HrtfEntry::IncRef() { - auto ref = IncrementRef(&this->ref); + auto ref = IncrementRef(this->ref); TRACEREF("HrtfEntry %p increasing refcount to %u\n", this, ref); } void HrtfEntry::DecRef() { - auto ref = DecrementRef(&this->ref); + auto ref = DecrementRef(this->ref); TRACEREF("HrtfEntry %p decreasing refcount to %u\n", this, ref); if(ref == 0) { @@ -1389,7 +1389,7 @@ void HrtfEntry::DecRef() auto delete_unused = [](HrtfHandlePtr &handle) -> void { HrtfEntry *entry{handle->entry.get()}; - if(entry && ReadRef(&entry->ref) == 0) + if(entry && ReadRef(entry->ref) == 0) { TRACE("Unloading unused HRTF %s\n", handle->filename.data()); handle->entry = nullptr; |