summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorGravatar Feng Chen2021-12-18 13:57:14 +0800
committerGravatar GitHub2021-12-18 13:57:14 +0800
commite49184e6069a9d791d2df3c1958f5c4b1187e124 (patch)
treeb776caf722e0be0e680f67b0ad0842628162ef1c /src/core/hle/kernel/kernel.cpp
parentImplement convert legacy to generic (diff)
parentMerge pull request #7570 from ameerj/favorites-expanded (diff)
downloadyuzu-e49184e6069a9d791d2df3c1958f5c4b1187e124.tar.gz
yuzu-e49184e6069a9d791d2df3c1958f5c4b1187e124.tar.xz
yuzu-e49184e6069a9d791d2df3c1958f5c4b1187e124.zip
Merge branch 'yuzu-emu:master' into convert_legacy
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp103
1 files changed, 62 insertions, 41 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index e42a6d36f..2e4e4cb1c 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -14,6 +14,7 @@
14#include "common/assert.h" 14#include "common/assert.h"
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "common/microprofile.h" 16#include "common/microprofile.h"
17#include "common/scope_exit.h"
17#include "common/thread.h" 18#include "common/thread.h"
18#include "common/thread_worker.h" 19#include "common/thread_worker.h"
19#include "core/arm/arm_interface.h" 20#include "core/arm/arm_interface.h"
@@ -83,12 +84,16 @@ struct KernelCore::Impl {
83 } 84 }
84 85
85 void InitializeCores() { 86 void InitializeCores() {
86 for (auto& core : cores) { 87 for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
87 core.Initialize(current_process->Is64BitProcess()); 88 cores[core_id].Initialize(current_process->Is64BitProcess());
89 system.Memory().SetCurrentPageTable(*current_process, core_id);
88 } 90 }
89 } 91 }
90 92
91 void Shutdown() { 93 void Shutdown() {
94 is_shutting_down.store(true, std::memory_order_relaxed);
95 SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); });
96
92 process_list.clear(); 97 process_list.clear();
93 98
94 // Close all open server ports. 99 // Close all open server ports.
@@ -123,15 +128,6 @@ struct KernelCore::Impl {
123 next_user_process_id = KProcess::ProcessIDMin; 128 next_user_process_id = KProcess::ProcessIDMin;
124 next_thread_id = 1; 129 next_thread_id = 1;
125 130
126 for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
127 if (suspend_threads[core_id]) {
128 suspend_threads[core_id]->Close();
129 suspend_threads[core_id] = nullptr;
130 }
131
132 schedulers[core_id].reset();
133 }
134
135 cores.clear(); 131 cores.clear();
136 132
137 global_handle_table->Finalize(); 133 global_handle_table->Finalize();
@@ -159,6 +155,16 @@ struct KernelCore::Impl {
159 CleanupObject(time_shared_mem); 155 CleanupObject(time_shared_mem);
160 CleanupObject(system_resource_limit); 156 CleanupObject(system_resource_limit);
161 157
158 for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
159 if (suspend_threads[core_id]) {
160 suspend_threads[core_id]->Close();
161 suspend_threads[core_id] = nullptr;
162 }
163
164 schedulers[core_id]->Finalize();
165 schedulers[core_id].reset();
166 }
167
162 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others 168 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
163 next_host_thread_id = Core::Hardware::NUM_CPU_CORES; 169 next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
164 170
@@ -245,13 +251,11 @@ struct KernelCore::Impl {
245 KScopedSchedulerLock lock(kernel); 251 KScopedSchedulerLock lock(kernel);
246 global_scheduler_context->PreemptThreads(); 252 global_scheduler_context->PreemptThreads();
247 } 253 }
248 const auto time_interval = std::chrono::nanoseconds{ 254 const auto time_interval = std::chrono::nanoseconds{std::chrono::milliseconds(10)};
249 Core::Timing::msToCycles(std::chrono::milliseconds(10))};
250 system.CoreTiming().ScheduleEvent(time_interval, preemption_event); 255 system.CoreTiming().ScheduleEvent(time_interval, preemption_event);
251 }); 256 });
252 257
253 const auto time_interval = 258 const auto time_interval = std::chrono::nanoseconds{std::chrono::milliseconds(10)};
254 std::chrono::nanoseconds{Core::Timing::msToCycles(std::chrono::milliseconds(10))};
255 system.CoreTiming().ScheduleEvent(time_interval, preemption_event); 259 system.CoreTiming().ScheduleEvent(time_interval, preemption_event);
256 } 260 }
257 261
@@ -267,14 +271,6 @@ struct KernelCore::Impl {
267 271
268 void MakeCurrentProcess(KProcess* process) { 272 void MakeCurrentProcess(KProcess* process) {
269 current_process = process; 273 current_process = process;
270 if (process == nullptr) {
271 return;
272 }
273
274 const u32 core_id = GetCurrentHostThreadID();
275 if (core_id < Core::Hardware::NUM_CPU_CORES) {
276 system.Memory().SetCurrentPageTable(*process, core_id);
277 }
278 } 274 }
279 275
280 static inline thread_local u32 host_thread_id = UINT32_MAX; 276 static inline thread_local u32 host_thread_id = UINT32_MAX;
@@ -300,15 +296,16 @@ struct KernelCore::Impl {
300 // Gets the dummy KThread for the caller, allocating a new one if this is the first time 296 // Gets the dummy KThread for the caller, allocating a new one if this is the first time
301 KThread* GetHostDummyThread() { 297 KThread* GetHostDummyThread() {
302 auto make_thread = [this]() { 298 auto make_thread = [this]() {
303 std::unique_ptr<KThread> thread = std::make_unique<KThread>(system.Kernel()); 299 std::lock_guard lk(dummy_thread_lock);
300 auto& thread = dummy_threads.emplace_back(std::make_unique<KThread>(system.Kernel()));
304 KAutoObject::Create(thread.get()); 301 KAutoObject::Create(thread.get());
305 ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); 302 ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess());
306 thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); 303 thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId()));
307 return thread; 304 return thread.get();
308 }; 305 };
309 306
310 thread_local auto thread = make_thread(); 307 thread_local KThread* saved_thread = make_thread();
311 return thread.get(); 308 return saved_thread;
312 } 309 }
313 310
314 /// Registers a CPU core thread by allocating a host thread ID for it 311 /// Registers a CPU core thread by allocating a host thread ID for it
@@ -343,7 +340,16 @@ struct KernelCore::Impl {
343 is_phantom_mode_for_singlecore = value; 340 is_phantom_mode_for_singlecore = value;
344 } 341 }
345 342
343 bool IsShuttingDown() const {
344 return is_shutting_down.load(std::memory_order_relaxed);
345 }
346
346 KThread* GetCurrentEmuThread() { 347 KThread* GetCurrentEmuThread() {
348 // If we are shutting down the kernel, none of this is relevant anymore.
349 if (IsShuttingDown()) {
350 return {};
351 }
352
347 const auto thread_id = GetCurrentHostThreadID(); 353 const auto thread_id = GetCurrentHostThreadID();
348 if (thread_id >= Core::Hardware::NUM_CPU_CORES) { 354 if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
349 return GetHostDummyThread(); 355 return GetHostDummyThread();
@@ -695,6 +701,12 @@ struct KernelCore::Impl {
695 return port; 701 return port;
696 } 702 }
697 703
704 std::mutex server_ports_lock;
705 std::mutex server_sessions_lock;
706 std::mutex registered_objects_lock;
707 std::mutex registered_in_use_objects_lock;
708 std::mutex dummy_thread_lock;
709
698 std::atomic<u32> next_object_id{0}; 710 std::atomic<u32> next_object_id{0};
699 std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; 711 std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin};
700 std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; 712 std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin};
@@ -725,10 +737,6 @@ struct KernelCore::Impl {
725 std::unordered_set<KServerSession*> server_sessions; 737 std::unordered_set<KServerSession*> server_sessions;
726 std::unordered_set<KAutoObject*> registered_objects; 738 std::unordered_set<KAutoObject*> registered_objects;
727 std::unordered_set<KAutoObject*> registered_in_use_objects; 739 std::unordered_set<KAutoObject*> registered_in_use_objects;
728 std::mutex server_ports_lock;
729 std::mutex server_sessions_lock;
730 std::mutex registered_objects_lock;
731 std::mutex registered_in_use_objects_lock;
732 740
733 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; 741 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
734 std::vector<Kernel::PhysicalCore> cores; 742 std::vector<Kernel::PhysicalCore> cores;
@@ -753,7 +761,11 @@ struct KernelCore::Impl {
753 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; 761 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
754 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; 762 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
755 763
764 // Specifically tracked to be automatically destroyed with kernel
765 std::vector<std::unique_ptr<KThread>> dummy_threads;
766
756 bool is_multicore{}; 767 bool is_multicore{};
768 std::atomic_bool is_shutting_down{};
757 bool is_phantom_mode_for_singlecore{}; 769 bool is_phantom_mode_for_singlecore{};
758 u32 single_core_thread_id{}; 770 u32 single_core_thread_id{};
759 771
@@ -839,16 +851,20 @@ const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const {
839 return impl->cores[id]; 851 return impl->cores[id];
840} 852}
841 853
854size_t KernelCore::CurrentPhysicalCoreIndex() const {
855 const u32 core_id = impl->GetCurrentHostThreadID();
856 if (core_id >= Core::Hardware::NUM_CPU_CORES) {
857 return Core::Hardware::NUM_CPU_CORES - 1;
858 }
859 return core_id;
860}
861
842Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() { 862Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() {
843 u32 core_id = impl->GetCurrentHostThreadID(); 863 return impl->cores[CurrentPhysicalCoreIndex()];
844 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
845 return impl->cores[core_id];
846} 864}
847 865
848const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const { 866const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
849 u32 core_id = impl->GetCurrentHostThreadID(); 867 return impl->cores[CurrentPhysicalCoreIndex()];
850 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
851 return impl->cores[core_id];
852} 868}
853 869
854Kernel::KScheduler* KernelCore::CurrentScheduler() { 870Kernel::KScheduler* KernelCore::CurrentScheduler() {
@@ -1051,6 +1067,9 @@ void KernelCore::Suspend(bool in_suspention) {
1051 impl->suspend_threads[core_id]->SetState(state); 1067 impl->suspend_threads[core_id]->SetState(state);
1052 impl->suspend_threads[core_id]->SetWaitReasonForDebugging( 1068 impl->suspend_threads[core_id]->SetWaitReasonForDebugging(
1053 ThreadWaitReasonForDebugging::Suspended); 1069 ThreadWaitReasonForDebugging::Suspended);
1070 if (!should_suspend) {
1071 impl->suspend_threads[core_id]->DisableDispatch();
1072 }
1054 } 1073 }
1055 } 1074 }
1056} 1075}
@@ -1059,19 +1078,21 @@ bool KernelCore::IsMulticore() const {
1059 return impl->is_multicore; 1078 return impl->is_multicore;
1060} 1079}
1061 1080
1081bool KernelCore::IsShuttingDown() const {
1082 return impl->IsShuttingDown();
1083}
1084
1062void KernelCore::ExceptionalExit() { 1085void KernelCore::ExceptionalExit() {
1063 exception_exited = true; 1086 exception_exited = true;
1064 Suspend(true); 1087 Suspend(true);
1065} 1088}
1066 1089
1067void KernelCore::EnterSVCProfile() { 1090void KernelCore::EnterSVCProfile() {
1068 std::size_t core = impl->GetCurrentHostThreadID(); 1091 impl->svc_ticks[CurrentPhysicalCoreIndex()] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
1069 impl->svc_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
1070} 1092}
1071 1093
1072void KernelCore::ExitSVCProfile() { 1094void KernelCore::ExitSVCProfile() {
1073 std::size_t core = impl->GetCurrentHostThreadID(); 1095 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
1074 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]);
1075} 1096}
1076 1097
1077std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { 1098std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {