summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2022-11-09 15:52:23 -0800
committerGravatar GitHub2022-11-09 15:52:23 -0800
commit770f23db341c6fad8c2647b6c0015348f6dc8730 (patch)
tree9cbb82f96454f27657a539e212f6f0852932ed35
parentMerge pull request #9215 from liamwhite/swordfight (diff)
parentservice_thread: register service threads to the logical owner process (diff)
downloadyuzu-770f23db341c6fad8c2647b6c0015348f6dc8730.tar.gz
yuzu-770f23db341c6fad8c2647b6c0015348f6dc8730.tar.xz
yuzu-770f23db341c6fad8c2647b6c0015348f6dc8730.zip
Merge pull request #9182 from liamwhite/services-are-processes
kernel: assign KProcess to service threads
-rw-r--r--src/core/hle/kernel/k_thread.cpp4
-rw-r--r--src/core/hle/kernel/k_thread.h2
-rw-r--r--src/core/hle/kernel/kernel.cpp49
-rw-r--r--src/core/hle/kernel/kernel.h2
-rw-r--r--src/core/hle/kernel/service_thread.cpp24
5 files changed, 56 insertions, 25 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index cc88d08f0..78076a346 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -263,9 +263,9 @@ Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_
263 R_SUCCEED(); 263 R_SUCCEED();
264} 264}
265 265
266Result KThread::InitializeDummyThread(KThread* thread) { 266Result KThread::InitializeDummyThread(KThread* thread, KProcess* owner) {
267 // Initialize the thread. 267 // Initialize the thread.
268 R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, {}, ThreadType::Dummy)); 268 R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy));
269 269
270 // Initialize emulation parameters. 270 // Initialize emulation parameters.
271 thread->stack_parameters.disable_count = 0; 271 thread->stack_parameters.disable_count = 0;
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 30aa10c9a..f38c92bff 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -415,7 +415,7 @@ public:
415 415
416 static void PostDestroy(uintptr_t arg); 416 static void PostDestroy(uintptr_t arg);
417 417
418 [[nodiscard]] static Result InitializeDummyThread(KThread* thread); 418 [[nodiscard]] static Result InitializeDummyThread(KThread* thread, KProcess* owner);
419 419
420 [[nodiscard]] static Result InitializeMainThread(Core::System& system, KThread* thread, 420 [[nodiscard]] static Result InitializeMainThread(Core::System& system, KThread* thread,
421 s32 virt_core); 421 s32 virt_core);
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index abff14079..7f800d860 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -91,7 +91,7 @@ struct KernelCore::Impl {
91 pt_heap_region.GetSize()); 91 pt_heap_region.GetSize());
92 } 92 }
93 93
94 RegisterHostThread(); 94 RegisterHostThread(nullptr);
95 95
96 default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread"); 96 default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread");
97 } 97 }
@@ -373,15 +373,18 @@ struct KernelCore::Impl {
373 } 373 }
374 374
375 // Gets the dummy KThread for the caller, allocating a new one if this is the first time 375 // Gets the dummy KThread for the caller, allocating a new one if this is the first time
376 KThread* GetHostDummyThread() { 376 KThread* GetHostDummyThread(KThread* existing_thread) {
377 auto initialize = [this](KThread* thread) { 377 auto initialize = [this](KThread* thread) {
378 ASSERT(KThread::InitializeDummyThread(thread).IsSuccess()); 378 ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
379 thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); 379 thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId()));
380 return thread; 380 return thread;
381 }; 381 };
382 382
383 thread_local auto raw_thread = KThread(system.Kernel()); 383 thread_local KThread raw_thread{system.Kernel()};
384 thread_local auto thread = initialize(&raw_thread); 384 thread_local KThread* thread = nullptr;
385 if (thread == nullptr) {
386 thread = (existing_thread == nullptr) ? initialize(&raw_thread) : existing_thread;
387 }
385 388
386 return thread; 389 return thread;
387 } 390 }
@@ -396,9 +399,9 @@ struct KernelCore::Impl {
396 } 399 }
397 400
398 /// Registers a new host thread by allocating a host thread ID for it 401 /// Registers a new host thread by allocating a host thread ID for it
399 void RegisterHostThread() { 402 void RegisterHostThread(KThread* existing_thread) {
400 [[maybe_unused]] const auto this_id = GetHostThreadId(); 403 [[maybe_unused]] const auto this_id = GetHostThreadId();
401 [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(); 404 [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread);
402 } 405 }
403 406
404 [[nodiscard]] u32 GetCurrentHostThreadID() { 407 [[nodiscard]] u32 GetCurrentHostThreadID() {
@@ -429,7 +432,7 @@ struct KernelCore::Impl {
429 KThread* GetCurrentEmuThread() { 432 KThread* GetCurrentEmuThread() {
430 const auto thread_id = GetCurrentHostThreadID(); 433 const auto thread_id = GetCurrentHostThreadID();
431 if (thread_id >= Core::Hardware::NUM_CPU_CORES) { 434 if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
432 return GetHostDummyThread(); 435 return GetHostDummyThread(nullptr);
433 } 436 }
434 437
435 return current_thread; 438 return current_thread;
@@ -1120,8 +1123,12 @@ void KernelCore::RegisterCoreThread(std::size_t core_id) {
1120 impl->RegisterCoreThread(core_id); 1123 impl->RegisterCoreThread(core_id);
1121} 1124}
1122 1125
1123void KernelCore::RegisterHostThread() { 1126void KernelCore::RegisterHostThread(KThread* existing_thread) {
1124 impl->RegisterHostThread(); 1127 impl->RegisterHostThread(existing_thread);
1128
1129 if (existing_thread != nullptr) {
1130 ASSERT(GetCurrentEmuThread() == existing_thread);
1131 }
1125} 1132}
1126 1133
1127u32 KernelCore::GetCurrentHostThreadID() const { 1134u32 KernelCore::GetCurrentHostThreadID() const {
@@ -1196,16 +1203,28 @@ void KernelCore::Suspend(bool suspended) {
1196 const bool should_suspend{exception_exited || suspended}; 1203 const bool should_suspend{exception_exited || suspended};
1197 const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; 1204 const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
1198 1205
1199 for (auto* process : GetProcessList()) { 1206 std::vector<KScopedAutoObject<KThread>> process_threads;
1200 process->SetActivity(activity); 1207 {
1208 KScopedSchedulerLock sl{*this};
1209
1210 if (auto* process = CurrentProcess(); process != nullptr) {
1211 process->SetActivity(activity);
1212
1213 if (!should_suspend) {
1214 // Runnable now; no need to wait.
1215 return;
1216 }
1201 1217
1202 if (should_suspend) {
1203 // Wait for execution to stop
1204 for (auto* thread : process->GetThreadList()) { 1218 for (auto* thread : process->GetThreadList()) {
1205 thread->WaitUntilSuspended(); 1219 process_threads.emplace_back(thread);
1206 } 1220 }
1207 } 1221 }
1208 } 1222 }
1223
1224 // Wait for execution to stop.
1225 for (auto& thread : process_threads) {
1226 thread->WaitUntilSuspended();
1227 }
1209} 1228}
1210 1229
1211void KernelCore::ShutdownCores() { 1230void KernelCore::ShutdownCores() {
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 29617d736..2e22fe0f6 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -240,7 +240,7 @@ public:
240 void RegisterCoreThread(std::size_t core_id); 240 void RegisterCoreThread(std::size_t core_id);
241 241
242 /// Register the current thread as a non CPU core thread. 242 /// Register the current thread as a non CPU core thread.
243 void RegisterHostThread(); 243 void RegisterHostThread(KThread* existing_thread = nullptr);
244 244
245 /// Gets the virtual memory manager for the kernel. 245 /// Gets the virtual memory manager for the kernel.
246 KMemoryManager& MemoryManager(); 246 KMemoryManager& MemoryManager();
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp
index c8fe42537..7a85be77f 100644
--- a/src/core/hle/kernel/service_thread.cpp
+++ b/src/core/hle/kernel/service_thread.cpp
@@ -36,11 +36,12 @@ public:
36private: 36private:
37 KernelCore& kernel; 37 KernelCore& kernel;
38 38
39 std::jthread m_thread; 39 std::jthread m_host_thread;
40 std::mutex m_session_mutex; 40 std::mutex m_session_mutex;
41 std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions; 41 std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions;
42 KEvent* m_wakeup_event; 42 KEvent* m_wakeup_event;
43 KProcess* m_process; 43 KProcess* m_process;
44 KThread* m_thread;
44 std::atomic<bool> m_shutdown_requested; 45 std::atomic<bool> m_shutdown_requested;
45 const std::string m_service_name; 46 const std::string m_service_name;
46}; 47};
@@ -132,7 +133,7 @@ void ServiceThread::Impl::SessionClosed(KServerSession* server_session,
132void ServiceThread::Impl::LoopProcess() { 133void ServiceThread::Impl::LoopProcess() {
133 Common::SetCurrentThreadName(m_service_name.c_str()); 134 Common::SetCurrentThreadName(m_service_name.c_str());
134 135
135 kernel.RegisterHostThread(); 136 kernel.RegisterHostThread(m_thread);
136 137
137 while (!m_shutdown_requested.load()) { 138 while (!m_shutdown_requested.load()) {
138 WaitAndProcessImpl(); 139 WaitAndProcessImpl();
@@ -160,7 +161,7 @@ ServiceThread::Impl::~Impl() {
160 // Shut down the processing thread. 161 // Shut down the processing thread.
161 m_shutdown_requested.store(true); 162 m_shutdown_requested.store(true);
162 m_wakeup_event->Signal(); 163 m_wakeup_event->Signal();
163 m_thread.join(); 164 m_host_thread.join();
164 165
165 // Lock mutex. 166 // Lock mutex.
166 m_session_mutex.lock(); 167 m_session_mutex.lock();
@@ -177,6 +178,9 @@ ServiceThread::Impl::~Impl() {
177 m_wakeup_event->GetReadableEvent().Close(); 178 m_wakeup_event->GetReadableEvent().Close();
178 m_wakeup_event->Close(); 179 m_wakeup_event->Close();
179 180
181 // Close thread.
182 m_thread->Close();
183
180 // Close process. 184 // Close process.
181 m_process->Close(); 185 m_process->Close();
182} 186}
@@ -199,11 +203,19 @@ ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name)
199 // Commit the event reservation. 203 // Commit the event reservation.
200 event_reservation.Commit(); 204 event_reservation.Commit();
201 205
202 // Register the event. 206 // Reserve a new thread from the process resource limit
203 KEvent::Register(kernel, m_wakeup_event); 207 KScopedResourceReservation thread_reservation(m_process, LimitableResource::Threads);
208 ASSERT(thread_reservation.Succeeded());
209
210 // Initialize thread.
211 m_thread = KThread::Create(kernel);
212 ASSERT(KThread::InitializeDummyThread(m_thread, m_process).IsSuccess());
213
214 // Commit the thread reservation.
215 thread_reservation.Commit();
204 216
205 // Start thread. 217 // Start thread.
206 m_thread = std::jthread([this] { LoopProcess(); }); 218 m_host_thread = std::jthread([this] { LoopProcess(); });
207} 219}
208 220
209ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name) 221ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name)