diff options
| author | 2020-12-15 00:41:48 -0800 | |
|---|---|---|
| committer | 2020-12-29 01:12:39 -0800 | |
| commit | dfdac7d38af170683812f3b474ef9d686dfa9ef8 (patch) | |
| tree | d72ff3fb593e6d42984b4d89863ae22cab3d77f5 | |
| parent | hle: kernel: service_thread: Add thread name and take weak_ptr of ServerSession. (diff) | |
| download | yuzu-dfdac7d38af170683812f3b474ef9d686dfa9ef8.tar.gz yuzu-dfdac7d38af170683812f3b474ef9d686dfa9ef8.tar.xz yuzu-dfdac7d38af170683812f3b474ef9d686dfa9ef8.zip | |
hle: kernel: Move ServiceThread ownership to KernelCore.
- Fixes a circular dependency which prevented threads from being released on shutdown.
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 17 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.h | 2 |
4 files changed, 48 insertions, 5 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 312c64c17..5f917686f 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include <functional> | 8 | #include <functional> |
| 9 | #include <memory> | 9 | #include <memory> |
| 10 | #include <thread> | 10 | #include <thread> |
| 11 | #include <unordered_map> | 11 | #include <unordered_set> |
| 12 | #include <utility> | 12 | #include <utility> |
| 13 | 13 | ||
| 14 | #include "common/assert.h" | 14 | #include "common/assert.h" |
| @@ -35,6 +35,7 @@ | |||
| 35 | #include "core/hle/kernel/physical_core.h" | 35 | #include "core/hle/kernel/physical_core.h" |
| 36 | #include "core/hle/kernel/process.h" | 36 | #include "core/hle/kernel/process.h" |
| 37 | #include "core/hle/kernel/resource_limit.h" | 37 | #include "core/hle/kernel/resource_limit.h" |
| 38 | #include "core/hle/kernel/service_thread.h" | ||
| 38 | #include "core/hle/kernel/shared_memory.h" | 39 | #include "core/hle/kernel/shared_memory.h" |
| 39 | #include "core/hle/kernel/synchronization.h" | 40 | #include "core/hle/kernel/synchronization.h" |
| 40 | #include "core/hle/kernel/thread.h" | 41 | #include "core/hle/kernel/thread.h" |
| @@ -107,6 +108,9 @@ struct KernelCore::Impl { | |||
| 107 | std::fill(register_host_thread_keys.begin(), register_host_thread_keys.end(), | 108 | std::fill(register_host_thread_keys.begin(), register_host_thread_keys.end(), |
| 108 | std::thread::id{}); | 109 | std::thread::id{}); |
| 109 | std::fill(register_host_thread_values.begin(), register_host_thread_values.end(), 0); | 110 | std::fill(register_host_thread_values.begin(), register_host_thread_values.end(), 0); |
| 111 | |||
| 112 | // Ensures all service threads gracefully shutdown | ||
| 113 | service_threads.clear(); | ||
| 110 | } | 114 | } |
| 111 | 115 | ||
| 112 | void InitializePhysicalCores() { | 116 | void InitializePhysicalCores() { |
| @@ -345,6 +349,9 @@ struct KernelCore::Impl { | |||
| 345 | std::shared_ptr<Kernel::SharedMemory> irs_shared_mem; | 349 | std::shared_ptr<Kernel::SharedMemory> irs_shared_mem; |
| 346 | std::shared_ptr<Kernel::SharedMemory> time_shared_mem; | 350 | std::shared_ptr<Kernel::SharedMemory> time_shared_mem; |
| 347 | 351 | ||
| 352 | // Threads used for services | ||
| 353 | std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; | ||
| 354 | |||
| 348 | std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; | 355 | std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; |
| 349 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; | 356 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; |
| 350 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; | 357 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; |
| @@ -639,4 +646,16 @@ void KernelCore::ExitSVCProfile() { | |||
| 639 | MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]); | 646 | MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]); |
| 640 | } | 647 | } |
| 641 | 648 | ||
| 649 | std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { | ||
| 650 | auto service_thread = std::make_shared<Kernel::ServiceThread>(*this, 1, name); | ||
| 651 | impl->service_threads.emplace(service_thread); | ||
| 652 | return service_thread; | ||
| 653 | } | ||
| 654 | |||
| 655 | void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { | ||
| 656 | if (auto strong_ptr = service_thread.lock()) { | ||
| 657 | impl->service_threads.erase(strong_ptr); | ||
| 658 | } | ||
| 659 | } | ||
| 660 | |||
| 642 | } // namespace Kernel | 661 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5846c3f39..e3169f5a7 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -42,6 +42,7 @@ class Process; | |||
| 42 | class ResourceLimit; | 42 | class ResourceLimit; |
| 43 | class KScheduler; | 43 | class KScheduler; |
| 44 | class SharedMemory; | 44 | class SharedMemory; |
| 45 | class ServiceThread; | ||
| 45 | class Synchronization; | 46 | class Synchronization; |
| 46 | class Thread; | 47 | class Thread; |
| 47 | class TimeManager; | 48 | class TimeManager; |
| @@ -227,6 +228,22 @@ public: | |||
| 227 | 228 | ||
| 228 | void ExitSVCProfile(); | 229 | void ExitSVCProfile(); |
| 229 | 230 | ||
| 231 | /** | ||
| 232 | * Creates an HLE service thread, which are used to execute service routines asynchronously. | ||
| 233 | * While these are allocated per ServerSession, these need to be owned and managed outside of | ||
| 234 | * ServerSession to avoid a circular dependency. | ||
| 235 | * @param name String name for the ServerSession creating this thread, used for debug purposes. | ||
| 236 | * @returns The a weak pointer newly created service thread. | ||
| 237 | */ | ||
| 238 | std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name); | ||
| 239 | |||
| 240 | /** | ||
| 241 | * Releases a HLE service thread, instructing KernelCore to free it. This should be called when | ||
| 242 | * the ServerSession associated with the thread is destroyed. | ||
| 243 | * @param service_thread Service thread to release. | ||
| 244 | */ | ||
| 245 | void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread); | ||
| 246 | |||
| 230 | private: | 247 | private: |
| 231 | friend class Object; | 248 | friend class Object; |
| 232 | friend class Process; | 249 | friend class Process; |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 947f4a133..b40fe3916 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -25,7 +25,10 @@ | |||
| 25 | namespace Kernel { | 25 | namespace Kernel { |
| 26 | 26 | ||
| 27 | ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {} | 27 | ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {} |
| 28 | ServerSession::~ServerSession() = default; | 28 | |
| 29 | ServerSession::~ServerSession() { | ||
| 30 | kernel.ReleaseServiceThread(service_thread); | ||
| 31 | } | ||
| 29 | 32 | ||
| 30 | ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, | 33 | ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, |
| 31 | std::shared_ptr<Session> parent, | 34 | std::shared_ptr<Session> parent, |
| @@ -34,7 +37,7 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern | |||
| 34 | 37 | ||
| 35 | session->name = std::move(name); | 38 | session->name = std::move(name); |
| 36 | session->parent = std::move(parent); | 39 | session->parent = std::move(parent); |
| 37 | session->service_thread = std::make_unique<ServiceThread>(kernel, 1, session->name); | 40 | session->service_thread = kernel.CreateServiceThread(session->name); |
| 38 | 41 | ||
| 39 | return MakeResult(std::move(session)); | 42 | return MakeResult(std::move(session)); |
| 40 | } | 43 | } |
| @@ -139,7 +142,11 @@ ResultCode ServerSession::QueueSyncRequest(std::shared_ptr<Thread> thread, | |||
| 139 | std::make_shared<HLERequestContext>(kernel, memory, SharedFrom(this), std::move(thread)); | 142 | std::make_shared<HLERequestContext>(kernel, memory, SharedFrom(this), std::move(thread)); |
| 140 | 143 | ||
| 141 | context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); | 144 | context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); |
| 142 | service_thread->QueueSyncRequest(*this, std::move(context)); | 145 | |
| 146 | if (auto strong_ptr = service_thread.lock()) { | ||
| 147 | strong_ptr->QueueSyncRequest(*this, std::move(context)); | ||
| 148 | return RESULT_SUCCESS; | ||
| 149 | } | ||
| 143 | 150 | ||
| 144 | return RESULT_SUCCESS; | 151 | return RESULT_SUCCESS; |
| 145 | } | 152 | } |
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 8466b03e6..e8d1d99ea 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h | |||
| @@ -167,7 +167,7 @@ private: | |||
| 167 | std::string name; | 167 | std::string name; |
| 168 | 168 | ||
| 169 | /// Thread to dispatch service requests | 169 | /// Thread to dispatch service requests |
| 170 | std::unique_ptr<ServiceThread> service_thread; | 170 | std::weak_ptr<ServiceThread> service_thread; |
| 171 | }; | 171 | }; |
| 172 | 172 | ||
| 173 | } // namespace Kernel | 173 | } // namespace Kernel |