summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/sink/cubeb_sink.cpp2
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp2
-rw-r--r--src/audio_core/sink/sink_stream.cpp12
-rw-r--r--src/audio_core/sink/sink_stream.h6
-rw-r--r--src/core/arm/arm_interface.cpp16
5 files changed, 26 insertions, 12 deletions
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp
index bbb598bc5..51a23fe15 100644
--- a/src/audio_core/sink/cubeb_sink.cpp
+++ b/src/audio_core/sink/cubeb_sink.cpp
@@ -146,7 +146,7 @@ public:
return;
}
- paused = true;
+ SignalPause();
if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
}
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index 7b89151de..96e0efce2 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -111,7 +111,7 @@ public:
if (device == 0 || paused) {
return;
}
- paused = true;
+ SignalPause();
SDL_PauseAudioDevice(device, 1);
}
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index d66d04fae..2a09db599 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -282,11 +282,19 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
void SinkStream::WaitFreeSpace(std::stop_token stop_token) {
std::unique_lock lk{release_mutex};
release_cv.wait_for(lk, std::chrono::milliseconds(5),
- [this]() { return queued_buffers < max_queue_size; });
+ [this]() { return paused || queued_buffers < max_queue_size; });
if (queued_buffers > max_queue_size + 3) {
Common::CondvarWait(release_cv, lk, stop_token,
- [this] { return queued_buffers < max_queue_size; });
+ [this] { return paused || queued_buffers < max_queue_size; });
}
}
+void SinkStream::SignalPause() {
+ {
+ std::scoped_lock lk{release_mutex};
+ paused = true;
+ }
+ release_cv.notify_one();
+}
+
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h
index 6a4996ca3..f2ccd19b8 100644
--- a/src/audio_core/sink/sink_stream.h
+++ b/src/audio_core/sink/sink_stream.h
@@ -214,6 +214,12 @@ public:
void WaitFreeSpace(std::stop_token stop_token);
protected:
+ /**
+ * Unblocks the ADSP if the stream is paused.
+ */
+ void SignalPause();
+
+protected:
/// Core system
Core::System& system;
/// Type of this stream
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 5e27dde58..558fba5bd 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -153,6 +153,14 @@ void ARM_Interface::Run() {
Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())};
HaltReason hr{};
+ // If the thread is scheduled for termination, exit the thread.
+ if (current_thread->HasDpc()) {
+ if (current_thread->IsTerminationRequested()) {
+ current_thread->Exit();
+ UNREACHABLE();
+ }
+ }
+
// Notify the debugger and go to sleep if a step was performed
// and this thread has been scheduled again.
if (current_thread->GetStepState() == StepState::StepPerformed) {
@@ -174,14 +182,6 @@ void ARM_Interface::Run() {
}
system.ExitCPUProfile();
- // If the thread is scheduled for termination, exit the thread.
- if (current_thread->HasDpc()) {
- if (current_thread->IsTerminationRequested()) {
- current_thread->Exit();
- UNREACHABLE();
- }
- }
-
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) {