aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-12-17 04:07:00 -0800
committerChris Robinson <[email protected]>2021-12-17 04:07:00 -0800
commitc9537abfb1a9d1c94d6bf9aa0e6cfa2cda1ae94b (patch)
tree294ac9a7fa7a921e2ae9320cc59ed8ca9a1117e5 /alc
parent21bdea776a1fca9f009470c6e5753cf78e208593 (diff)
Allocate voice properties in clusters
Diffstat (limited to 'alc')
-rw-r--r--alc/alc.cpp21
-rw-r--r--alc/context.cpp29
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};