diff options
author | Chris Robinson <[email protected]> | 2021-12-17 04:07:00 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-12-17 04:07:00 -0800 |
commit | c9537abfb1a9d1c94d6bf9aa0e6cfa2cda1ae94b (patch) | |
tree | 294ac9a7fa7a921e2ae9320cc59ed8ca9a1117e5 /alc | |
parent | 21bdea776a1fca9f009470c6e5753cf78e208593 (diff) |
Allocate voice properties in clusters
Diffstat (limited to 'alc')
-rw-r--r-- | alc/alc.cpp | 21 | ||||
-rw-r--r-- | alc/context.cpp | 29 |
2 files changed, 27 insertions, 23 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp index 54162d14..89c836d0 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2082,18 +2082,6 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) } } - /* Clear any pre-existing voice property structs, in case the number of - * auxiliary sends is changing. Active sources will have updates - * respecified in UpdateAllSourceProps. - */ - VoicePropsItem *vprops{context->mFreeVoiceProps.exchange(nullptr, std::memory_order_acq_rel)}; - while(vprops) - { - VoicePropsItem *next = vprops->next.load(std::memory_order_relaxed); - delete vprops; - vprops = next; - } - auto voicelist = context->getVoicesSpan(); for(Voice *voice : voicelist) { @@ -2108,7 +2096,8 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) SendParams{}); } - delete voice->mUpdate.exchange(nullptr, std::memory_order_acq_rel); + if(VoicePropsItem *props{voice->mUpdate.exchange(nullptr, std::memory_order_relaxed)}) + AtomicReplaceHead(context->mFreeVoiceProps, props); /* Force the voice to stopped if it was stopping. */ Voice::State vstate{Voice::Stopping}; @@ -2119,6 +2108,9 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) voice->prepare(device); } + /* Clear all voice props to let them get allocated again. */ + context->mVoicePropClusters.clear(); + context->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed); srclock.unlock(); context->mPropsDirty.test_and_clear(std::memory_order_release); @@ -2173,6 +2165,9 @@ bool ResetDeviceParams(ALCdevice *device, const int *attrList) vchg = next; ctx->mCurrentVoiceChange.store(vchg, std::memory_order_release); + ctx->mVoicePropClusters.clear(); + ctx->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed); + ctx->mVoiceClusters.clear(); ctx->allocVoices(std::max<size_t>(256, ctx->mActiveVoiceCount.load(std::memory_order_relaxed))); diff --git a/alc/context.cpp b/alc/context.cpp index a97c2a68..297d24a6 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -133,16 +133,6 @@ ContextBase::~ContextBase() delete curarray; } - count = 0; - VoicePropsItem *vprops{mFreeVoiceProps.exchange(nullptr, std::memory_order_acquire)}; - while(vprops) - { - std::unique_ptr<VoicePropsItem> old{vprops}; - vprops = old->next.load(std::memory_order_relaxed); - ++count; - } - TRACE("Freed %zu voice property object%s\n", count, (count==1)?"":"s"); - delete mVoices.exchange(nullptr, std::memory_order_relaxed); count = 0; @@ -198,6 +188,25 @@ void ContextBase::allocVoiceChanges(size_t addcount) } } +void ContextBase::allocVoiceProps() +{ + constexpr size_t clustersize{32}; + + TRACE("Increasing allocated voice properties to %zu\n", + (mVoicePropClusters.size()+1) * clustersize); + + VoicePropsCluster cluster{std::make_unique<VoicePropsItem[]>(clustersize)}; + for(size_t i{1};i < clustersize;++i) + cluster[i-1].next.store(std::addressof(cluster[i]), std::memory_order_relaxed); + mVoicePropClusters.emplace_back(std::move(cluster)); + + VoicePropsItem *oldhead{mFreeVoiceProps.load(std::memory_order_acquire)}; + do { + mVoicePropClusters.back()[clustersize-1].next.store(oldhead, std::memory_order_relaxed); + } while(mFreeVoiceProps.compare_exchange_weak(oldhead, mVoicePropClusters.back().get(), + std::memory_order_acq_rel, std::memory_order_acquire) == false); +} + void ContextBase::allocVoices(size_t addcount) { constexpr size_t clustersize{32}; |