summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2022-01-14 22:22:39 -0800
committerGravatar GitHub2022-01-14 22:22:39 -0800
commit5eda606952c5ff635c0e3ac6ae47686b58d4e045 (patch)
treecb670f33d2be1515b471c3564c18f47b84add15a /src
parentMerge pull request #7707 from german77/slow-update (diff)
parenthle: kernel: Fix service_threads access to be thread safe V2. (diff)
downloadyuzu-5eda606952c5ff635c0e3ac6ae47686b58d4e045.tar.gz
yuzu-5eda606952c5ff635c0e3ac6ae47686b58d4e045.tar.xz
yuzu-5eda606952c5ff635c0e3ac6ae47686b58d4e045.zip
Merge pull request #7711 from bunnei/fix-service-thread-race-v2
hle: kernel: Fix service_threads access to be thread safe V2.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/kernel.cpp23
1 files changed, 11 insertions, 12 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index e1e17db13..0b618fb46 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -51,7 +51,8 @@ namespace Kernel {
51 51
52struct KernelCore::Impl { 52struct KernelCore::Impl {
53 explicit Impl(Core::System& system_, KernelCore& kernel_) 53 explicit Impl(Core::System& system_, KernelCore& kernel_)
54 : time_manager{system_}, object_list_container{kernel_}, system{system_} {} 54 : time_manager{system_}, object_list_container{kernel_},
55 service_threads_manager{1, "yuzu:ServiceThreadsManager"}, system{system_} {}
55 56
56 void SetMulticore(bool is_multi) { 57 void SetMulticore(bool is_multi) {
57 is_multicore = is_multi; 58 is_multicore = is_multi;
@@ -707,24 +708,22 @@ struct KernelCore::Impl {
707 std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel, 708 std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel,
708 const std::string& name) { 709 const std::string& name) {
709 auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, 1, name); 710 auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, 1, name);
710 { 711
711 std::lock_guard lk(service_threads_lock); 712 service_threads_manager.QueueWork(
712 service_threads.emplace(service_thread); 713 [this, service_thread]() { service_threads.emplace(service_thread); });
713 } 714
714 return service_thread; 715 return service_thread;
715 } 716 }
716 717
717 void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { 718 void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
718 auto strong_ptr = service_thread.lock(); 719 if (auto strong_ptr = service_thread.lock()) {
719 { 720 service_threads_manager.QueueWork(
720 std::lock_guard lk(service_threads_lock); 721 [this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); });
721 service_threads.erase(strong_ptr);
722 } 722 }
723 } 723 }
724 724
725 void ClearServiceThreads() { 725 void ClearServiceThreads() {
726 std::lock_guard lk(service_threads_lock); 726 service_threads_manager.QueueWork([this]() { service_threads.clear(); });
727 service_threads.clear();
728 } 727 }
729 728
730 std::mutex server_ports_lock; 729 std::mutex server_ports_lock;
@@ -732,7 +731,6 @@ struct KernelCore::Impl {
732 std::mutex registered_objects_lock; 731 std::mutex registered_objects_lock;
733 std::mutex registered_in_use_objects_lock; 732 std::mutex registered_in_use_objects_lock;
734 std::mutex dummy_thread_lock; 733 std::mutex dummy_thread_lock;
735 std::mutex service_threads_lock;
736 734
737 std::atomic<u32> next_object_id{0}; 735 std::atomic<u32> next_object_id{0};
738 std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; 736 std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin};
@@ -783,6 +781,7 @@ struct KernelCore::Impl {
783 781
784 // Threads used for services 782 // Threads used for services
785 std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; 783 std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads;
784 Common::ThreadWorker service_threads_manager;
786 785
787 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; 786 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads;
788 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; 787 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};