diff --git a/src/audio_core/adsp/apps/opus/opus_decoder.cpp b/src/audio_core/adsp/apps/opus/opus_decoder.cpp index 83d000df35..ef39afb117 100644 --- a/src/audio_core/adsp/apps/opus/opus_decoder.cpp +++ b/src/audio_core/adsp/apps/opus/opus_decoder.cpp @@ -41,19 +41,16 @@ OpusDecoder::OpusDecoder(Core::System& system_) : system{system_} { } OpusDecoder::~OpusDecoder() { - if (!running) { + if (main_thread.joinable()) { + // Shutdown the thread + Send(Direction::DSP, Message::Shutdown); + main_thread.request_stop(); + auto msg = Receive(Direction::Host, main_thread.get_stop_token()); + ASSERT_MSG(msg == Message::ShutdownOK, "Expected Opus shutdown code {}, got {}", Message::ShutdownOK, msg); + main_thread.join(); + } else { init_thread.request_stop(); - return; } - - // Shutdown the thread - Send(Direction::DSP, Message::Shutdown); - auto msg = Receive(Direction::Host); - ASSERT_MSG(msg == Message::ShutdownOK, "Expected Opus shutdown code {}, got {}", - Message::ShutdownOK, msg); - main_thread.request_stop(); - main_thread.join(); - running = false; } void OpusDecoder::Send(Direction dir, u32 message) { @@ -73,7 +70,6 @@ void OpusDecoder::Init(std::stop_token stop_token) { return; } main_thread = std::jthread([this](std::stop_token st) { Main(st); }); - running = true; Send(Direction::Host, Message::StartOK); } diff --git a/src/audio_core/adsp/apps/opus/opus_decoder.h b/src/audio_core/adsp/apps/opus/opus_decoder.h index 1cae3b455a..40fbd39089 100644 --- a/src/audio_core/adsp/apps/opus/opus_decoder.h +++ b/src/audio_core/adsp/apps/opus/opus_decoder.h @@ -57,7 +57,7 @@ public: ~OpusDecoder(); bool IsRunning() const noexcept { - return running; + return main_thread.joinable(); } void Send(Direction dir, u32 message); @@ -87,8 +87,6 @@ private: std::jthread init_thread{}; /// Main thread std::jthread main_thread{}; - /// The current state - bool running{}; /// Structure shared with the host, input data set by the host before sending a mailbox message, /// and the responses are written back by the OpusDecoder. SharedMemory* shared_memory{}; diff --git a/src/core/hle/kernel/k_worker_task_manager.cpp b/src/core/hle/kernel/k_worker_task_manager.cpp index 742d743022..9764d51b5f 100644 --- a/src/core/hle/kernel/k_worker_task_manager.cpp +++ b/src/core/hle/kernel/k_worker_task_manager.cpp @@ -6,6 +6,7 @@ #include #include "common/assert.h" +#include "common/thread.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_worker_task.h" @@ -27,7 +28,23 @@ void KWorkerTask::DoWorkerTask(KernelCore& kernel) { } } -KWorkerTaskManager::KWorkerTaskManager() {} +KWorkerTaskManager::KWorkerTaskManager(KernelCore& kernel) { + m_waiting_thread = std::jthread([&kernel, this](std::stop_token stop_token) { + Common::SetCurrentThreadName("KWorkerManager"); + while (!stop_token.stop_requested()) { + KWorkerTask* t; + { + std::unique_lock lk{m_task_mutex}; + m_task_cv.wait(lk); + if (stop_token.stop_requested()) + break; + t = m_task_queue.back(); + m_task_queue.pop_back(); + } + t->DoWorkerTask(kernel); + } + }); +} KWorkerTaskManager::~KWorkerTaskManager() { if (m_waiting_thread.joinable()) { @@ -44,26 +61,6 @@ void KWorkerTaskManager::AddTask(KernelCore& kernel, WorkerType type, KWorkerTas void KWorkerTaskManager::AddTask(KernelCore& kernel, KWorkerTask* task) { KScopedSchedulerLock sl(kernel); - - // spawn thread on demand - if (!m_waiting_thread.joinable()) { - LOG_INFO(Kernel, "spawning KWorkerTaskManager thread"); - m_waiting_thread = std::jthread([&kernel, this](std::stop_token stop_token) { - while (!stop_token.stop_requested()) { - KWorkerTask* t; - { - std::unique_lock lk{m_task_mutex}; - m_task_cv.wait(lk); - if (stop_token.stop_requested()) - break; - t = m_task_queue.back(); - m_task_queue.pop_back(); - } - t->DoWorkerTask(kernel); - } - }); - } - { std::scoped_lock lk{m_task_mutex}; m_task_queue.emplace_back(task); diff --git a/src/core/hle/kernel/k_worker_task_manager.h b/src/core/hle/kernel/k_worker_task_manager.h index 58e819b3f4..00a3974d3f 100644 --- a/src/core/hle/kernel/k_worker_task_manager.h +++ b/src/core/hle/kernel/k_worker_task_manager.h @@ -23,7 +23,7 @@ public: Count, }; - KWorkerTaskManager(); + KWorkerTaskManager(KernelCore& kernel); ~KWorkerTaskManager(); static void AddTask(KernelCore& kernel, WorkerType type, KWorkerTask* task); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 591033618c..580aae8510 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -81,7 +81,8 @@ struct KernelCore::Impl { static inline thread_local ThreadLocalData tls_data = {}; explicit Impl(Core::System& system_, KernelCore& kernel_) - : system{system_} + : worker_task_manager{kernel_} + , system{system_} { tls_data.lock = true; }