summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2020-12-15 00:41:48 -0800
committerGravatar bunnei2020-12-29 01:12:39 -0800
commitdfdac7d38af170683812f3b474ef9d686dfa9ef8 (patch)
treed72ff3fb593e6d42984b4d89863ae22cab3d77f5
parenthle: kernel: service_thread: Add thread name and take weak_ptr of ServerSession. (diff)
downloadyuzu-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.cpp21
-rw-r--r--src/core/hle/kernel/kernel.h17
-rw-r--r--src/core/hle/kernel/server_session.cpp13
-rw-r--r--src/core/hle/kernel/server_session.h2
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
649std::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
655void 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;
42class ResourceLimit; 42class ResourceLimit;
43class KScheduler; 43class KScheduler;
44class SharedMemory; 44class SharedMemory;
45class ServiceThread;
45class Synchronization; 46class Synchronization;
46class Thread; 47class Thread;
47class TimeManager; 48class 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
230private: 247private:
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 @@
25namespace Kernel { 25namespace Kernel {
26 26
27ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {} 27ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {}
28ServerSession::~ServerSession() = default; 28
29ServerSession::~ServerSession() {
30 kernel.ReleaseServiceThread(service_thread);
31}
29 32
30ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, 33ResultVal<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