aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2024-01-03 14:12:28 -0800
committerChris Robinson <[email protected]>2024-01-03 14:12:28 -0800
commited98cbefd014a5166ec086fd276eb283cdab22aa (patch)
tree321f7efe504a010572c15277114883cc72cced34
parentf8604758bc7cc43efa52a305a578ee9cf474f0d6 (diff)
Allocate context property updates in clusters
-rw-r--r--al/state.cpp16
-rw-r--r--core/context.cpp36
-rw-r--r--core/context.h7
3 files changed, 37 insertions, 22 deletions
diff --git a/al/state.cpp b/al/state.cpp
index d9c199d5..c1e3d593 100644
--- a/al/state.cpp
+++ b/al/state.cpp
@@ -643,18 +643,18 @@ AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value) noexcept
void UpdateContextProps(ALCcontext *context)
{
- /* Get an unused proprty container, or allocate a new one as needed. */
+ /* Get an unused property container, or allocate a new one as needed. */
ContextProps *props{context->mFreeContextProps.load(std::memory_order_acquire)};
if(!props)
- props = new ContextProps{};
- else
{
- ContextProps *next;
- do {
- next = props->next.load(std::memory_order_relaxed);
- } while(context->mFreeContextProps.compare_exchange_weak(props, next,
- std::memory_order_seq_cst, std::memory_order_acquire) == 0);
+ context->allocContextProps();
+ props = context->mFreeContextProps.load(std::memory_order_acquire);
}
+ ContextProps *next;
+ do {
+ next = props->next.load(std::memory_order_relaxed);
+ } while(context->mFreeContextProps.compare_exchange_weak(props, next,
+ std::memory_order_acq_rel, std::memory_order_acquire) == false);
/* Copy in current property values. */
ALlistener &listener = context->mListener;
diff --git a/core/context.cpp b/core/context.cpp
index 46f703a9..0fe50d25 100644
--- a/core/context.cpp
+++ b/core/context.cpp
@@ -27,19 +27,6 @@ ContextBase::ContextBase(DeviceBase *device) : mDevice{device}
ContextBase::~ContextBase()
{
- size_t count{0};
- ContextProps *cprops{mParams.ContextUpdate.exchange(nullptr, std::memory_order_relaxed)};
- if(std::unique_ptr<ContextProps> old{cprops})
- ++count;
-
- cprops = mFreeContextProps.exchange(nullptr, std::memory_order_acquire);
- while(std::unique_ptr<ContextProps> old{cprops})
- {
- cprops = old->next.load(std::memory_order_relaxed);
- ++count;
- }
- TRACE("Freed %zu context property object%s\n", count, (count==1)?"":"s");
-
if(std::unique_ptr<EffectSlotArray> curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)})
std::destroy_n(curarray->end(), curarray->size());
@@ -47,7 +34,7 @@ ContextBase::~ContextBase()
if(mAsyncEvents)
{
- count = 0;
+ size_t count{0};
auto evt_vec = mAsyncEvents->getReadVector();
if(evt_vec.first.len > 0)
{
@@ -177,3 +164,24 @@ EffectSlot *ContextBase::getEffectSlot()
mEffectSlotClusters.emplace_back(std::move(clusterptr));
return mEffectSlotClusters.back()->data();
}
+
+
+void ContextBase::allocContextProps()
+{
+ static constexpr size_t clustersize{std::tuple_size_v<ContextPropsCluster::element_type>};
+
+ TRACE("Increasing allocated context properties to %zu\n",
+ (mContextPropClusters.size()+1) * clustersize);
+
+ auto clusterptr = std::make_unique<ContextPropsCluster::element_type>();
+ auto cluster = al::span{*clusterptr};
+ for(size_t i{1};i < clustersize;++i)
+ cluster[i-1].next.store(std::addressof(cluster[i]), std::memory_order_relaxed);
+ auto *newcluster = mContextPropClusters.emplace_back(std::move(clusterptr)).get();
+
+ ContextProps *oldhead{mFreeContextProps.load(std::memory_order_acquire)};
+ do {
+ newcluster->back().next.store(oldhead, std::memory_order_relaxed);
+ } while(mFreeContextProps.compare_exchange_weak(oldhead, newcluster->data(),
+ std::memory_order_acq_rel, std::memory_order_acquire) == false);
+}
diff --git a/core/context.h b/core/context.h
index 16d1b415..980514b3 100644
--- a/core/context.h
+++ b/core/context.h
@@ -108,6 +108,7 @@ struct ContextBase {
void allocVoiceChanges();
void allocVoiceProps();
void allocEffectSlotProps();
+ void allocContextProps();
ContextParams mParams;
@@ -160,6 +161,12 @@ struct ContextBase {
using EffectSlotPropsCluster = std::unique_ptr<std::array<EffectSlotProps,4>>;
std::vector<EffectSlotPropsCluster> mEffectSlotPropClusters;
+ /* This could be greater than 2, but there should be no way there can be
+ * more than two context property updates in use simultaneously.
+ */
+ using ContextPropsCluster = std::unique_ptr<std::array<ContextProps,2>>;
+ std::vector<ContextPropsCluster> mContextPropClusters;
+
ContextBase(DeviceBase *device);
ContextBase(const ContextBase&) = delete;