summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2022-11-09 15:52:23 -0800
committerGravatar GitHub2022-11-09 15:52:23 -0800
commit770f23db341c6fad8c2647b6c0015348f6dc8730 (patch)
tree9cbb82f96454f27657a539e212f6f0852932ed35 /src/core/hle/kernel/kernel.cpp
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
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp49
1 files changed, 34 insertions, 15 deletions
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() {