diff options
| author | bunnei <bunneidev@gmail.com> | 2020-12-29 16:39:04 -0800 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2020-12-29 16:46:29 -0800 | 
| commit | a2a0f5318dba2c87578703a5bb69b9fbf7ec526d (patch) | |
| tree | 9d153419ffd306af3c13137223e8a85a5f33e9bc /src/core/hle/kernel | |
| parent | 69e82d01d5012c0078f65a294ecbb7118707f73c (diff) | |
hle: kernel: Manage service threads on another thread.
- This is to allow service threads to defer destruction of themselves.
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 29 | 
1 files changed, 20 insertions, 9 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 022cd413d..e8ece8164 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -15,6 +15,7 @@  #include "common/logging/log.h"  #include "common/microprofile.h"  #include "common/thread.h" +#include "common/thread_worker.h"  #include "core/arm/arm_interface.h"  #include "core/arm/cpu_interrupt_handler.h"  #include "core/arm/exclusive_monitor.h" @@ -58,11 +59,11 @@ struct KernelCore::Impl {      }      void Initialize(KernelCore& kernel) { -        process_list.clear(); -          RegisterHostThread();          global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); +        service_thread_manager = +            std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager");          InitializePhysicalCores();          InitializeSystemResourceLimit(kernel); @@ -79,6 +80,12 @@ struct KernelCore::Impl {      }      void Shutdown() { +        process_list.clear(); + +        // Ensures all service threads gracefully shutdown +        service_thread_manager.reset(); +        service_threads.clear(); +          next_object_id = 0;          next_kernel_process_id = Process::InitialKIPIDMin;          next_user_process_id = Process::ProcessIDMin; @@ -106,9 +113,6 @@ struct KernelCore::Impl {          // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others          next_host_thread_id = Core::Hardware::NUM_CPU_CORES; - -        // Ensures all service threads gracefully shutdown -        service_threads.clear();      }      void InitializePhysicalCores() { @@ -337,6 +341,10 @@ struct KernelCore::Impl {      // Threads used for services      std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; +    // Service threads are managed by a worker thread, so that a calling service thread can queue up +    // the release of itself +    std::unique_ptr<Common::ThreadWorker> service_thread_manager; +      std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{};      std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};      std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; @@ -633,14 +641,17 @@ void KernelCore::ExitSVCProfile() {  std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {      auto service_thread = std::make_shared<Kernel::ServiceThread>(*this, 1, name); -    impl->service_threads.emplace(service_thread); +    impl->service_thread_manager->QueueWork( +        [this, service_thread] { impl->service_threads.emplace(service_thread); });      return service_thread;  }  void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { -    if (auto strong_ptr = service_thread.lock()) { -        impl->service_threads.erase(strong_ptr); -    } +    impl->service_thread_manager->QueueWork([this, service_thread] { +        if (auto strong_ptr = service_thread.lock()) { +            impl->service_threads.erase(strong_ptr); +        } +    });  }  } // namespace Kernel  | 
