summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2021-01-29 23:06:40 -0800
committerGravatar GitHub2021-01-29 23:06:40 -0800
commita4526c4e1acb50808bbe205952101142288e1c60 (patch)
tree7109edf89606c43352da9de40d0e3a920a08b659 /src/core/hle/kernel/kernel.cpp
parentMerge pull request #5795 from ReinUsesLisp/bytes-to-map-end (diff)
parenthle: kernel: KLightLock: Fix several bugs. (diff)
downloadyuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.gz
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.xz
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.zip
Merge pull request #5779 from bunnei/kthread-rewrite
Rewrite KThread to be more accurate
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp76
1 files changed, 49 insertions, 27 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index c0ff287a6..df309d523 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -29,6 +29,7 @@
29#include "core/hle/kernel/errors.h" 29#include "core/hle/kernel/errors.h"
30#include "core/hle/kernel/handle_table.h" 30#include "core/hle/kernel/handle_table.h"
31#include "core/hle/kernel/k_scheduler.h" 31#include "core/hle/kernel/k_scheduler.h"
32#include "core/hle/kernel/k_thread.h"
32#include "core/hle/kernel/kernel.h" 33#include "core/hle/kernel/kernel.h"
33#include "core/hle/kernel/memory/memory_layout.h" 34#include "core/hle/kernel/memory/memory_layout.h"
34#include "core/hle/kernel/memory/memory_manager.h" 35#include "core/hle/kernel/memory/memory_manager.h"
@@ -38,7 +39,6 @@
38#include "core/hle/kernel/resource_limit.h" 39#include "core/hle/kernel/resource_limit.h"
39#include "core/hle/kernel/service_thread.h" 40#include "core/hle/kernel/service_thread.h"
40#include "core/hle/kernel/shared_memory.h" 41#include "core/hle/kernel/shared_memory.h"
41#include "core/hle/kernel/thread.h"
42#include "core/hle/kernel/time_manager.h" 42#include "core/hle/kernel/time_manager.h"
43#include "core/hle/lock.h" 43#include "core/hle/lock.h"
44#include "core/hle/result.h" 44#include "core/hle/result.h"
@@ -57,11 +57,13 @@ struct KernelCore::Impl {
57 } 57 }
58 58
59 void Initialize(KernelCore& kernel) { 59 void Initialize(KernelCore& kernel) {
60 global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
61
60 RegisterHostThread(); 62 RegisterHostThread();
61 63
62 global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
63 service_thread_manager = 64 service_thread_manager =
64 std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); 65 std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager");
66 is_phantom_mode_for_singlecore = false;
65 67
66 InitializePhysicalCores(); 68 InitializePhysicalCores();
67 InitializeSystemResourceLimit(kernel); 69 InitializeSystemResourceLimit(kernel);
@@ -116,14 +118,14 @@ struct KernelCore::Impl {
116 void InitializePhysicalCores() { 118 void InitializePhysicalCores() {
117 exclusive_monitor = 119 exclusive_monitor =
118 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); 120 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES);
119 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 121 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
120 schedulers[i] = std::make_unique<Kernel::KScheduler>(system, i); 122 schedulers[i] = std::make_unique<Kernel::KScheduler>(system, i);
121 cores.emplace_back(i, system, *schedulers[i], interrupts); 123 cores.emplace_back(i, system, *schedulers[i], interrupts);
122 } 124 }
123 } 125 }
124 126
125 void InitializeSchedulers() { 127 void InitializeSchedulers() {
126 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 128 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
127 cores[i].Scheduler().Initialize(); 129 cores[i].Scheduler().Initialize();
128 } 130 }
129 } 131 }
@@ -168,11 +170,9 @@ struct KernelCore::Impl {
168 std::string name = "Suspend Thread Id:" + std::to_string(i); 170 std::string name = "Suspend Thread Id:" + std::to_string(i);
169 std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); 171 std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc();
170 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); 172 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
171 const auto type = 173 auto thread_res = KThread::Create(system, ThreadType::HighPriority, std::move(name), 0,
172 static_cast<ThreadType>(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_SUSPEND); 174 0, 0, static_cast<u32>(i), 0, nullptr,
173 auto thread_res = 175 std::move(init_func), init_func_parameter);
174 Thread::Create(system, type, std::move(name), 0, 0, 0, static_cast<u32>(i), 0,
175 nullptr, std::move(init_func), init_func_parameter);
176 176
177 suspend_threads[i] = std::move(thread_res).Unwrap(); 177 suspend_threads[i] = std::move(thread_res).Unwrap();
178 } 178 }
@@ -207,6 +207,17 @@ struct KernelCore::Impl {
207 return host_thread_id; 207 return host_thread_id;
208 } 208 }
209 209
210 // Gets the dummy KThread for the caller, allocating a new one if this is the first time
211 KThread* GetHostDummyThread() {
212 const thread_local auto thread =
213 KThread::Create(
214 system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0,
215 KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr,
216 []([[maybe_unused]] void* arg) { UNREACHABLE(); }, nullptr)
217 .Unwrap();
218 return thread.get();
219 }
220
210 /// Registers a CPU core thread by allocating a host thread ID for it 221 /// Registers a CPU core thread by allocating a host thread ID for it
211 void RegisterCoreThread(std::size_t core_id) { 222 void RegisterCoreThread(std::size_t core_id) {
212 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); 223 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
@@ -219,6 +230,7 @@ struct KernelCore::Impl {
219 /// Registers a new host thread by allocating a host thread ID for it 230 /// Registers a new host thread by allocating a host thread ID for it
220 void RegisterHostThread() { 231 void RegisterHostThread() {
221 [[maybe_unused]] const auto this_id = GetHostThreadId(); 232 [[maybe_unused]] const auto this_id = GetHostThreadId();
233 [[maybe_unused]] const auto dummy_thread = GetHostDummyThread();
222 } 234 }
223 235
224 [[nodiscard]] u32 GetCurrentHostThreadID() { 236 [[nodiscard]] u32 GetCurrentHostThreadID() {
@@ -229,20 +241,21 @@ struct KernelCore::Impl {
229 return this_id; 241 return this_id;
230 } 242 }
231 243
232 [[nodiscard]] Core::EmuThreadHandle GetCurrentEmuThreadID() { 244 bool IsPhantomModeForSingleCore() const {
233 Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); 245 return is_phantom_mode_for_singlecore;
234 result.host_handle = GetCurrentHostThreadID(); 246 }
235 if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { 247
236 return result; 248 void SetIsPhantomModeForSingleCore(bool value) {
237 } 249 ASSERT(!is_multicore);
238 const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler(); 250 is_phantom_mode_for_singlecore = value;
239 const Kernel::Thread* current = sched.GetCurrentThread(); 251 }
240 if (current != nullptr && !current->IsPhantomMode()) { 252
241 result.guest_handle = current->GetGlobalHandle(); 253 KThread* GetCurrentEmuThread() {
242 } else { 254 const auto thread_id = GetCurrentHostThreadID();
243 result.guest_handle = InvalidHandle; 255 if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
256 return GetHostDummyThread();
244 } 257 }
245 return result; 258 return schedulers[thread_id]->GetCurrentThread();
246 } 259 }
247 260
248 void InitializeMemoryLayout() { 261 void InitializeMemoryLayout() {
@@ -342,11 +355,12 @@ struct KernelCore::Impl {
342 // the release of itself 355 // the release of itself
343 std::unique_ptr<Common::ThreadWorker> service_thread_manager; 356 std::unique_ptr<Common::ThreadWorker> service_thread_manager;
344 357
345 std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; 358 std::array<std::shared_ptr<KThread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{};
346 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; 359 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
347 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; 360 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
348 361
349 bool is_multicore{}; 362 bool is_multicore{};
363 bool is_phantom_mode_for_singlecore{};
350 u32 single_core_thread_id{}; 364 u32 single_core_thread_id{};
351 365
352 std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{}; 366 std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{};
@@ -380,8 +394,8 @@ std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const {
380 return impl->system_resource_limit; 394 return impl->system_resource_limit;
381} 395}
382 396
383std::shared_ptr<Thread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { 397std::shared_ptr<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const {
384 return impl->global_handle_table.Get<Thread>(handle); 398 return impl->global_handle_table.Get<KThread>(handle);
385} 399}
386 400
387void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { 401void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) {
@@ -546,8 +560,8 @@ u32 KernelCore::GetCurrentHostThreadID() const {
546 return impl->GetCurrentHostThreadID(); 560 return impl->GetCurrentHostThreadID();
547} 561}
548 562
549Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const { 563KThread* KernelCore::GetCurrentEmuThread() const {
550 return impl->GetCurrentEmuThreadID(); 564 return impl->GetCurrentEmuThread();
551} 565}
552 566
553Memory::MemoryManager& KernelCore::MemoryManager() { 567Memory::MemoryManager& KernelCore::MemoryManager() {
@@ -645,4 +659,12 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi
645 }); 659 });
646} 660}
647 661
662bool KernelCore::IsPhantomModeForSingleCore() const {
663 return impl->IsPhantomModeForSingleCore();
664}
665
666void KernelCore::SetIsPhantomModeForSingleCore(bool value) {
667 impl->SetIsPhantomModeForSingleCore(value);
668}
669
648} // namespace Kernel 670} // namespace Kernel