diff options
| author | 2021-01-29 23:06:40 -0800 | |
|---|---|---|
| committer | 2021-01-29 23:06:40 -0800 | |
| commit | a4526c4e1acb50808bbe205952101142288e1c60 (patch) | |
| tree | 7109edf89606c43352da9de40d0e3a920a08b659 /src/core/hle/kernel/kernel.cpp | |
| parent | Merge pull request #5795 from ReinUsesLisp/bytes-to-map-end (diff) | |
| parent | hle: kernel: KLightLock: Fix several bugs. (diff) | |
| download | yuzu-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.cpp | 76 |
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 | ||
| 383 | std::shared_ptr<Thread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { | 397 | std::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 | ||
| 387 | void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { | 401 | void 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 | ||
| 549 | Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const { | 563 | KThread* KernelCore::GetCurrentEmuThread() const { |
| 550 | return impl->GetCurrentEmuThreadID(); | 564 | return impl->GetCurrentEmuThread(); |
| 551 | } | 565 | } |
| 552 | 566 | ||
| 553 | Memory::MemoryManager& KernelCore::MemoryManager() { | 567 | Memory::MemoryManager& KernelCore::MemoryManager() { |
| @@ -645,4 +659,12 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi | |||
| 645 | }); | 659 | }); |
| 646 | } | 660 | } |
| 647 | 661 | ||
| 662 | bool KernelCore::IsPhantomModeForSingleCore() const { | ||
| 663 | return impl->IsPhantomModeForSingleCore(); | ||
| 664 | } | ||
| 665 | |||
| 666 | void KernelCore::SetIsPhantomModeForSingleCore(bool value) { | ||
| 667 | impl->SetIsPhantomModeForSingleCore(value); | ||
| 668 | } | ||
| 669 | |||
| 648 | } // namespace Kernel | 670 | } // namespace Kernel |