From 8f6245be9a344f53cfca6804bf883a491d113dae Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 26 Nov 2022 13:46:38 -0800 Subject: [PATCH 1/2] core: Use atomic instead of a lock to protect is_paused. - This allows us to call IsPaused() elsewhere if we are holding the suspend lock. --- src/core/core.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index d8934be52..94d4e2212 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -189,7 +189,7 @@ struct System::Impl { kernel.Suspend(false); core_timing.SyncPause(false); - is_paused = false; + is_paused.store(false, std::memory_order_relaxed); return status; } @@ -200,14 +200,13 @@ struct System::Impl { core_timing.SyncPause(true); kernel.Suspend(true); - is_paused = true; + is_paused.store(true, std::memory_order_relaxed); return status; } bool IsPaused() const { - std::unique_lock lk(suspend_guard); - return is_paused; + return is_paused.load(std::memory_order_relaxed); } std::unique_lock StallProcesses() { @@ -218,7 +217,7 @@ struct System::Impl { } void UnstallProcesses() { - if (!is_paused) { + if (!IsPaused()) { core_timing.SyncPause(false); kernel.Suspend(false); } @@ -465,7 +464,7 @@ struct System::Impl { } mutable std::mutex suspend_guard; - bool is_paused{}; + std::atomic_bool is_paused{}; std::atomic is_shutting_down{}; Timing::CoreTiming core_timing; From 8fd4e44014119a1c155de64d63d455390f852a22 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 29 Nov 2022 20:32:06 -0800 Subject: [PATCH 2/2] audio_core: sink_stream: Hold the suspend lock when process is stalled. - Prevents us from clashing with other callers trying to un/stall. --- src/audio_core/sink/sink_stream.cpp | 11 ++++++----- src/audio_core/sink/sink_stream.h | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index 849f862b0..67e194e3c 100644 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp @@ -266,19 +266,20 @@ void SinkStream::ProcessAudioOutAndRender(std::span output_buffer, std::siz } void SinkStream::Stall() { - if (stalled) { + std::scoped_lock lk{stall_guard}; + if (stalled_lock) { return; } - stalled = true; - system.StallProcesses(); + stalled_lock = system.StallProcesses(); } void SinkStream::Unstall() { - if (!stalled) { + std::scoped_lock lk{stall_guard}; + if (!stalled_lock) { return; } system.UnstallProcesses(); - stalled = false; + stalled_lock.unlock(); } } // namespace AudioCore::Sink diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h index 38a4b2f51..5fea72ab7 100644 --- a/src/audio_core/sink/sink_stream.h +++ b/src/audio_core/sink/sink_stream.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -240,8 +241,8 @@ private: f32 system_volume{1.0f}; /// Set via IAudioDevice service calls f32 device_volume{1.0f}; - /// True if coretiming has been stalled - bool stalled{false}; + std::mutex stall_guard; + std::unique_lock stalled_lock; }; using SinkStreamPtr = std::unique_ptr;