audio_renderer: resolve adsp thread deadlock shutdown
This commit is contained in:
parent
125a0e5a07
commit
e96a3a1713
|
@ -105,7 +105,7 @@ void AudioRenderer::Start(AudioRenderer_Mailbox* mailbox_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mailbox = mailbox_;
|
mailbox = mailbox_;
|
||||||
thread = std::thread(&AudioRenderer::ThreadFunc, this);
|
thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(stop_token); });
|
||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ void AudioRenderer::CreateSinkStreams() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRenderer::ThreadFunc() {
|
void AudioRenderer::ThreadFunc(std::stop_token stop_token) {
|
||||||
static constexpr char name[]{"AudioRenderer"};
|
static constexpr char name[]{"AudioRenderer"};
|
||||||
MicroProfileOnThreadCreate(name);
|
MicroProfileOnThreadCreate(name);
|
||||||
Common::SetCurrentThreadName(name);
|
Common::SetCurrentThreadName(name);
|
||||||
|
@ -146,7 +146,7 @@ void AudioRenderer::ThreadFunc() {
|
||||||
|
|
||||||
constexpr u64 max_process_time{2'304'000ULL};
|
constexpr u64 max_process_time{2'304'000ULL};
|
||||||
|
|
||||||
while (true) {
|
while (!stop_token.stop_requested()) {
|
||||||
auto message{mailbox->ADSPWaitMessage()};
|
auto message{mailbox->ADSPWaitMessage()};
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case RenderMessage::AudioRenderer_Shutdown:
|
case RenderMessage::AudioRenderer_Shutdown:
|
||||||
|
@ -194,7 +194,7 @@ void AudioRenderer::ThreadFunc() {
|
||||||
max_time = std::min(command_buffer.time_limit, max_time);
|
max_time = std::min(command_buffer.time_limit, max_time);
|
||||||
command_list_processor.SetProcessTimeMax(max_time);
|
command_list_processor.SetProcessTimeMax(max_time);
|
||||||
|
|
||||||
streams[index]->WaitFreeSpace();
|
streams[index]->WaitFreeSpace(stop_token);
|
||||||
|
|
||||||
// Process the command list
|
// Process the command list
|
||||||
{
|
{
|
||||||
|
|
|
@ -177,7 +177,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Main AudioRenderer thread, responsible for processing the command lists.
|
* Main AudioRenderer thread, responsible for processing the command lists.
|
||||||
*/
|
*/
|
||||||
void ThreadFunc();
|
void ThreadFunc(std::stop_token stop_token);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the streams which will receive the processed samples.
|
* Creates the streams which will receive the processed samples.
|
||||||
|
@ -187,7 +187,7 @@ private:
|
||||||
/// Core system
|
/// Core system
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
/// Main thread
|
/// Main thread
|
||||||
std::thread thread{};
|
std::jthread thread{};
|
||||||
/// The current state
|
/// The current state
|
||||||
std::atomic<bool> running{};
|
std::atomic<bool> running{};
|
||||||
/// The active mailbox
|
/// The active mailbox
|
||||||
|
|
|
@ -269,12 +269,13 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
|
||||||
return std::min<u64>(exp_played_sample_count, max_played_sample_count) + TargetSampleCount * 3;
|
return std::min<u64>(exp_played_sample_count, max_played_sample_count) + TargetSampleCount * 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SinkStream::WaitFreeSpace() {
|
void SinkStream::WaitFreeSpace(std::stop_token stop_token) {
|
||||||
std::unique_lock lk{release_mutex};
|
std::unique_lock lk{release_mutex};
|
||||||
release_cv.wait_for(lk, std::chrono::milliseconds(5),
|
release_cv.wait_for(lk, std::chrono::milliseconds(5),
|
||||||
[this]() { return queued_buffers < max_queue_size; });
|
[this]() { return queued_buffers < max_queue_size; });
|
||||||
if (queued_buffers > max_queue_size + 3) {
|
if (queued_buffers > max_queue_size + 3) {
|
||||||
release_cv.wait(lk, [this]() { return queued_buffers < max_queue_size; });
|
Common::CondvarWait(release_cv, lk, stop_token,
|
||||||
|
[this] { return queued_buffers < max_queue_size; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "audio_core/common/common.h"
|
#include "audio_core/common/common.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/polyfill_thread.h"
|
||||||
#include "common/reader_writer_queue.h"
|
#include "common/reader_writer_queue.h"
|
||||||
#include "common/ring_buffer.h"
|
#include "common/ring_buffer.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
|
@ -210,7 +211,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Waits for free space in the sample ring buffer
|
* Waits for free space in the sample ring buffer
|
||||||
*/
|
*/
|
||||||
void WaitFreeSpace();
|
void WaitFreeSpace(std::stop_token stop_token);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Core system
|
/// Core system
|
||||||
|
@ -252,7 +253,7 @@ private:
|
||||||
/// Set via IAudioDevice service calls
|
/// Set via IAudioDevice service calls
|
||||||
f32 device_volume{1.0f};
|
f32 device_volume{1.0f};
|
||||||
/// Signalled when ring buffer entries are consumed
|
/// Signalled when ring buffer entries are consumed
|
||||||
std::condition_variable release_cv;
|
std::condition_variable_any release_cv;
|
||||||
std::mutex release_mutex;
|
std::mutex release_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue