diff options
author | Chris Robinson <[email protected]> | 2024-01-01 15:54:30 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2024-01-01 15:54:30 -0800 |
commit | 70a8cf88041d88c49dcd258587e6b84960752851 (patch) | |
tree | 50acfdf6587a68e985aa713567b2e997cb5eef4f | |
parent | 936e654b261b4d1cb604a44da534ba385aa10099 (diff) |
Use an atomic unique_ptr for the device's context array
-rw-r--r-- | alc/alc.cpp | 13 | ||||
-rw-r--r-- | alc/context.cpp | 18 | ||||
-rw-r--r-- | core/device.cpp | 12 | ||||
-rw-r--r-- | core/device.h | 7 |
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); |