diff options
author | Chris Robinson <[email protected]> | 2023-12-04 01:18:49 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-12-04 02:25:05 -0800 |
commit | e123e7bbda4330559ef03a5362bc93064eb87e4e (patch) | |
tree | 5dc77aeefd6ae7576f8cc8fb0b7c5a35ad7ee46d /core | |
parent | b6a68e8d510610e181d638ff993e327059bd6018 (diff) |
Use RAII to handle writing under the mixer seqlock
Diffstat (limited to 'core')
-rw-r--r-- | core/device.h | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/core/device.h b/core/device.h index 1f3c5105..1ac01ba6 100644 --- a/core/device.h +++ b/core/device.h @@ -284,7 +284,7 @@ struct DeviceBase { * the end, so the bottom bit indicates if the device is currently mixing * and the upper bits indicates how many mixes have been done. */ - std::atomic<uint> MixCount{0u}; + std::atomic<uint> mMixCount{0u}; // Contexts created on this device std::atomic<al::FlexArray<ContextBase*>*> mContexts{nullptr}; @@ -299,10 +299,34 @@ struct DeviceBase { uint channelsFromFmt() const noexcept { return ChannelsFromDevFmt(FmtChans, mAmbiOrder); } uint frameSizeFromFmt() const noexcept { return bytesFromFmt() * channelsFromFmt(); } + struct MixLock { + std::atomic<uint> &mCount; + const uint mLastVal; + + MixLock(std::atomic<uint> &count, const uint last_val) noexcept + : mCount{count}, mLastVal{last_val} + { } + /* Increment the mix count when the lock goes out of scope to "release" + * it (lsb should be 0). + */ + ~MixLock() { mCount.store(mLastVal+2, std::memory_order_release); } + }; + auto getWriteMixLock() noexcept + { + /* Increment the mix count at the start of mixing and writing clock + * info (lsb should be 1). + */ + const auto mixCount = mMixCount.load(std::memory_order_relaxed); + mMixCount.store(mixCount+1, std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_release); + return MixLock{mMixCount, mixCount}; + } + + /** Waits for the mixer to not be mixing or updating the clock. */ uint waitForMix() const noexcept { uint refcount; - while((refcount=MixCount.load(std::memory_order_acquire))&1) { + while((refcount=mMixCount.load(std::memory_order_acquire))&1) { } return refcount; } |