aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-12-16 18:41:47 -0800
committerChris Robinson <[email protected]>2022-12-16 18:41:47 -0800
commitd281ffa9ce3abd8dfd5afd72914acebe4a4a92ff (patch)
tree59612d00cc9efa076c3565a743eab93378532326 /core
parent84cfef8513b88068e8ef66223d09b6c48d35caad (diff)
Use a bitset for the enabled event flags
Diffstat (limited to 'core')
-rw-r--r--core/async_event.h20
-rw-r--r--core/context.cpp7
-rw-r--r--core/context.h5
-rw-r--r--core/voice.cpp6
4 files changed, 23 insertions, 15 deletions
diff --git a/core/async_event.h b/core/async_event.h
index 750f38c9..5a2f5f91 100644
--- a/core/async_event.h
+++ b/core/async_event.h
@@ -10,16 +10,17 @@ using uint = unsigned int;
struct AsyncEvent {
enum : uint {
- /* End event thread processing. */
- KillThread = 0,
-
/* User event types. */
- SourceStateChange = 1<<0,
- BufferCompleted = 1<<1,
- Disconnected = 1<<2,
+ SourceStateChange,
+ BufferCompleted,
+ Disconnected,
+ UserEventCount,
- /* Internal events. */
- ReleaseEffectState = 65536,
+ /* Internal events, always processed. */
+ ReleaseEffectState = 128,
+
+ /* End event thread processing. */
+ KillThread,
};
enum class SrcState {
@@ -29,7 +30,7 @@ struct AsyncEvent {
Pause
};
- uint EnumType{0u};
+ const uint EnumType;
union {
char dummy;
struct {
@@ -46,7 +47,6 @@ struct AsyncEvent {
EffectState *mEffectState;
} u{};
- AsyncEvent() noexcept = default;
constexpr AsyncEvent(uint type) noexcept : EnumType{type} { }
DISABLE_ALLOC()
diff --git a/core/context.cpp b/core/context.cpp
index 111802d9..d68d8327 100644
--- a/core/context.cpp
+++ b/core/context.cpp
@@ -1,6 +1,7 @@
#include "config.h"
+#include <cassert>
#include <memory>
#include "async_event.h"
@@ -13,8 +14,12 @@
#include "voice_change.h"
+#ifdef __cpp_lib_atomic_is_always_lock_free
+static_assert(std::atomic<ContextBase::AsyncEventBitset>::is_always_lock_free, "atomic<bitset> isn't lock-free");
+#endif
+
ContextBase::ContextBase(DeviceBase *device) : mDevice{device}
-{ }
+{ assert(mEnabledEvts.is_lock_free()); }
ContextBase::~ContextBase()
{
diff --git a/core/context.h b/core/context.h
index 4e3ea195..9723eac3 100644
--- a/core/context.h
+++ b/core/context.h
@@ -3,12 +3,14 @@
#include <array>
#include <atomic>
+#include <bitset>
#include <cstddef>
#include <memory>
#include <thread>
#include "almalloc.h"
#include "alspan.h"
+#include "async_event.h"
#include "atomic.h"
#include "bufferline.h"
#include "threads.h"
@@ -135,7 +137,8 @@ struct ContextBase {
std::thread mEventThread;
al::semaphore mEventSem;
std::unique_ptr<RingBuffer> mAsyncEvents;
- std::atomic<uint> mEnabledEvts{0u};
+ using AsyncEventBitset = std::bitset<AsyncEvent::UserEventCount>;
+ std::atomic<AsyncEventBitset> mEnabledEvts{0u};
/* Asynchronous voice change actions are processed as a linked list of
* VoiceChange objects by the mixer, which is atomically appended to.
diff --git a/core/voice.cpp b/core/voice.cpp
index c8810c36..eab8f851 100644
--- a/core/voice.cpp
+++ b/core/voice.cpp
@@ -849,8 +849,8 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi
std::atomic_thread_fence(std::memory_order_release);
/* Send any events now, after the position/buffer info was updated. */
- const uint enabledevt{Context->mEnabledEvts.load(std::memory_order_acquire)};
- if(buffers_done > 0 && (enabledevt&AsyncEvent::BufferCompleted))
+ const auto enabledevt = Context->mEnabledEvts.load(std::memory_order_acquire);
+ if(buffers_done > 0 && enabledevt.test(AsyncEvent::BufferCompleted))
{
RingBuffer *ring{Context->mAsyncEvents.get()};
auto evt_vec = ring->getWriteVector();
@@ -870,7 +870,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi
* ensures any residual noise fades to 0 amplitude.
*/
mPlayState.store(Stopping, std::memory_order_release);
- if((enabledevt&AsyncEvent::SourceStateChange))
+ if(enabledevt.test(AsyncEvent::SourceStateChange))
SendSourceStoppedEvent(Context, SourceID);
}
}