aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2024-01-01 15:54:30 -0800
committerChris Robinson <[email protected]>2024-01-01 15:54:30 -0800
commit70a8cf88041d88c49dcd258587e6b84960752851 (patch)
tree50acfdf6587a68e985aa713567b2e997cb5eef4f
parent936e654b261b4d1cb604a44da534ba385aa10099 (diff)
Use an atomic unique_ptr for the device's context array
-rw-r--r--alc/alc.cpp13
-rw-r--r--alc/context.cpp18
-rw-r--r--core/device.cpp12
-rw-r--r--core/device.h7
4 files changed, 13 insertions, 37 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp
index af68e4d0..cc25177d 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -2719,8 +2719,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
* old array.
*/
auto *oldarray = device->mContexts.load();
- const size_t newcount{oldarray->size()+1};
- std::unique_ptr<ContextArray> newarray{ContextArray::Create(newcount)};
+ auto newarray = ContextArray::Create(oldarray->size() + 1);
/* Copy the current/old context handles to the new array, appending the
* new context.
@@ -2731,12 +2730,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
/* Store the new context array in the device. Wait for any current mix
* to finish before deleting the old array.
*/
- dev->mContexts.store(newarray.release());
- if(oldarray != &DeviceBase::sEmptyContextArray)
- {
- std::ignore = dev->waitForMix();
- newarray.reset(oldarray);
- }
+ auto prevarray = dev->mContexts.exchange(std::move(newarray));
+ std::ignore = dev->waitForMix();
}
statelock.unlock();
@@ -2817,7 +2812,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) noexc
* the current context as its refcount is decremented.
*/
}
- ContextRef{ALCcontext::sGlobalContext.exchange(ctx.release())};
+ ctx = ContextRef{ALCcontext::sGlobalContext.exchange(ctx.release())};
ALCcontext::sGlobalContextLock.store(false, std::memory_order_release);
/* Take ownership of the thread-local context reference (if any), clearing
diff --git a/alc/context.cpp b/alc/context.cpp
index 0f6dbbae..67f08aee 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -263,12 +263,8 @@ void ALCcontext::deinit()
if(auto toremove = static_cast<size_t>(std::count(oldarray->begin(), oldarray->end(), this)))
{
using ContextArray = al::FlexArray<ContextBase*>;
- auto alloc_ctx_array = [](const size_t count) -> ContextArray*
- {
- if(count == 0) return &DeviceBase::sEmptyContextArray;
- return ContextArray::Create(count).release();
- };
- auto *newarray = alloc_ctx_array(oldarray->size() - toremove);
+ const size_t newsize{oldarray->size() - toremove};
+ auto newarray = ContextArray::Create(newsize);
/* Copy the current/old context handles to the new array, excluding the
* given context.
@@ -279,14 +275,10 @@ void ALCcontext::deinit()
/* Store the new context array in the device. Wait for any current mix
* to finish before deleting the old array.
*/
- mDevice->mContexts.store(newarray);
- if(oldarray != &DeviceBase::sEmptyContextArray)
- {
- std::ignore = mDevice->waitForMix();
- delete oldarray;
- }
+ auto prevarray = mDevice->mContexts.exchange(std::move(newarray));
+ std::ignore = mDevice->waitForMix();
- stopPlayback = newarray->empty();
+ stopPlayback = (newsize == 0);
}
else
stopPlayback = oldarray->empty();
diff --git a/core/device.cpp b/core/device.cpp
index a5edf63c..795a9601 100644
--- a/core/device.cpp
+++ b/core/device.cpp
@@ -12,15 +12,9 @@
static_assert(std::atomic<std::chrono::nanoseconds>::is_always_lock_free);
-al::FlexArray<ContextBase*> DeviceBase::sEmptyContextArray{0u};
-
-
-DeviceBase::DeviceBase(DeviceType type) : Type{type}, mContexts{&sEmptyContextArray}
+DeviceBase::DeviceBase(DeviceType type)
+ : Type{type}, mContexts{al::FlexArray<ContextBase*>::Create(0)}
{
}
-DeviceBase::~DeviceBase()
-{
- auto *oldarray = mContexts.exchange(nullptr, std::memory_order_relaxed);
- if(oldarray != &sEmptyContextArray) delete oldarray;
-}
+DeviceBase::~DeviceBase() = default;
diff --git a/core/device.h b/core/device.h
index 9ee07454..1da08727 100644
--- a/core/device.h
+++ b/core/device.h
@@ -181,11 +181,6 @@ enum class DeviceState : uint8_t {
};
struct DeviceBase {
- /* To avoid extraneous allocations, a 0-sized FlexArray<ContextBase*> is
- * defined globally as a sharable object.
- */
- static al::FlexArray<ContextBase*> sEmptyContextArray;
-
std::atomic<bool> Connected{true};
const DeviceType Type{};
@@ -295,7 +290,7 @@ struct DeviceBase {
std::atomic<uint> mMixCount{0u};
// Contexts created on this device
- std::atomic<al::FlexArray<ContextBase*>*> mContexts{nullptr};
+ al::atomic_unique_ptr<al::FlexArray<ContextBase*>> mContexts;
DeviceBase(DeviceType type);