Merge pull request #10611 from liamwhite/audio-deadlock
audio_renderer: resolve adsp thread deadlock shutdown
This commit is contained in:
		| @@ -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; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user