From 0728dfef84ded5e68bdb3b0781ea00ca7cc85659 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 13 Feb 2020 22:04:10 -0400 Subject: Kernel: Make global scheduler depend on KernelCore --- src/core/hle/kernel/kernel.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 4eb1d8703..d312ae31e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -97,8 +97,8 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ } struct KernelCore::Impl { - explicit Impl(Core::System& system) - : system{system}, global_scheduler{system}, synchronization{system} {} + explicit Impl(Core::System& system, KernelCore& kernel) + : system{system}, global_scheduler{kernel}, synchronization{system} {} void Initialize(KernelCore& kernel) { Shutdown(); @@ -215,7 +215,7 @@ struct KernelCore::Impl { Core::System& system; }; -KernelCore::KernelCore(Core::System& system) : impl{std::make_unique(system)} {} +KernelCore::KernelCore(Core::System& system) : impl{std::make_unique(system, *this)} {} KernelCore::~KernelCore() { Shutdown(); } @@ -265,6 +265,14 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { return impl->global_scheduler; } +Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) { + return impl->cores[id].Scheduler(); +} + +const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const { + return impl->cores[id].Scheduler(); +} + Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { return impl->cores[id]; } -- cgit v1.2.3 From 179bafa7cb1efae5405d38ea9b98dc6b3e1ec756 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 14 Feb 2020 09:30:53 -0400 Subject: Kernel: Rename ThreadCallbackHandleTable and Setup Thread Ids on Kernel. --- src/core/hle/kernel/kernel.cpp | 88 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 12 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d312ae31e..b3a5d7505 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include "common/assert.h" @@ -44,7 +46,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ std::lock_guard lock{HLE::g_hle_lock}; std::shared_ptr thread = - system.Kernel().RetrieveThreadFromWakeupCallbackHandleTable(proper_handle); + system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle); if (thread == nullptr) { LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle); return; @@ -120,7 +122,7 @@ struct KernelCore::Impl { system_resource_limit = nullptr; - thread_wakeup_callback_handle_table.Clear(); + global_handle_table.Clear(); thread_wakeup_event_type = nullptr; preemption_event = nullptr; @@ -138,8 +140,8 @@ struct KernelCore::Impl { void InitializePhysicalCores() { exclusive_monitor = - Core::MakeExclusiveMonitor(system.Memory(), global_scheduler.CpuCoresCount()); - for (std::size_t i = 0; i < global_scheduler.CpuCoresCount(); i++) { + Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); + for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { cores.emplace_back(system, i, *exclusive_monitor); } } @@ -184,6 +186,48 @@ struct KernelCore::Impl { system.Memory().SetCurrentPageTable(*process); } + void RegisterCoreThread(std::size_t core_id) { + const std::thread::id this_id = std::this_thread::get_id(); + const auto it = host_thread_ids.find(this_id); + ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); + ASSERT(it == host_thread_ids.end()); + ASSERT(!registered_core_threads[core_id]); + host_thread_ids[this_id] = static_cast(core_id); + registered_core_threads.set(core_id); + } + + void RegisterHostThread() { + const std::thread::id this_id = std::this_thread::get_id(); + const auto it = host_thread_ids.find(this_id); + ASSERT(it == host_thread_ids.end()); + host_thread_ids[this_id] = registered_thread_ids++; + } + + u32 GetCurrentHostThreadId() const { + const std::thread::id this_id = std::this_thread::get_id(); + const auto it = host_thread_ids.find(this_id); + if (it == host_thread_ids.end()) { + return Core::INVALID_HOST_THREAD_ID; + } + return it->second; + } + + Core::EmuThreadHandle GetCurrentEmuThreadId() const { + Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); + result.host_handle = GetCurrentHostThreadId(); + if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { + return result; + } + const Kernel::Scheduler& sched = cores[result.host_handle].Scheduler(); + const Kernel::Thread* current = sched.GetCurrentThread(); + if (current != nullptr) { + result.guest_handle = current->GetGlobalHandle(); + } else { + result.guest_handle = InvalidHandle; + } + return result; + } + std::atomic next_object_id{0}; std::atomic next_kernel_process_id{Process::InitialKIPIDMin}; std::atomic next_user_process_id{Process::ProcessIDMin}; @@ -202,7 +246,7 @@ struct KernelCore::Impl { // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, // allowing us to simply use a pool index or similar. - Kernel::HandleTable thread_wakeup_callback_handle_table; + Kernel::HandleTable global_handle_table; /// Map of named ports managed by the kernel, which can be retrieved using /// the ConnectToPort SVC. @@ -211,6 +255,11 @@ struct KernelCore::Impl { std::unique_ptr exclusive_monitor; std::vector cores; + // 0-3 Ids represent core threads, >3 represent others + std::unordered_map host_thread_ids; + u32 registered_thread_ids{Core::Hardware::NUM_CPU_CORES}; + std::bitset registered_core_threads{}; + // System context Core::System& system; }; @@ -232,9 +281,8 @@ std::shared_ptr KernelCore::GetSystemResourceLimit() const { return impl->system_resource_limit; } -std::shared_ptr KernelCore::RetrieveThreadFromWakeupCallbackHandleTable( - Handle handle) const { - return impl->thread_wakeup_callback_handle_table.Get(handle); +std::shared_ptr KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { + return impl->global_handle_table.Get(handle); } void KernelCore::AppendNewProcess(std::shared_ptr process) { @@ -346,12 +394,28 @@ const std::shared_ptr& KernelCore::ThreadWakeupCallback return impl->thread_wakeup_event_type; } -Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() { - return impl->thread_wakeup_callback_handle_table; +Kernel::HandleTable& KernelCore::GlobalHandleTable() { + return impl->global_handle_table; +} + +const Kernel::HandleTable& KernelCore::GlobalHandleTable() const { + return impl->global_handle_table; +} + +void KernelCore::RegisterCoreThread(std::size_t core_id) { + impl->RegisterCoreThread(core_id); +} + +void KernelCore::RegisterHostThread() { + impl->RegisterHostThread(); +} + +u32 KernelCore::GetCurrentHostThreadId() const { + return impl->GetCurrentHostThreadId(); } -const Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() const { - return impl->thread_wakeup_callback_handle_table; +Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadId() const { + return impl->GetCurrentEmuThreadId(); } } // namespace Kernel -- cgit v1.2.3 From 5c90d22f3d92b9be818b19e03dd57eb217eb6567 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 14 Feb 2020 10:56:27 -0400 Subject: Kernel: Implement Time Manager. --- src/core/hle/kernel/kernel.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b3a5d7505..de14e1936 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -27,6 +27,7 @@ #include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/synchronization.h" #include "core/hle/kernel/thread.h" +#include "core/hle/kernel/time_manager.h" #include "core/hle/lock.h" #include "core/hle/result.h" #include "core/memory.h" @@ -100,7 +101,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ struct KernelCore::Impl { explicit Impl(Core::System& system, KernelCore& kernel) - : system{system}, global_scheduler{kernel}, synchronization{system} {} + : system{system}, global_scheduler{kernel}, synchronization{system}, time_manager{system} {} void Initialize(KernelCore& kernel) { Shutdown(); @@ -238,6 +239,7 @@ struct KernelCore::Impl { Process* current_process = nullptr; Kernel::GlobalScheduler global_scheduler; Kernel::Synchronization synchronization; + Kernel::TimeManager time_manager; std::shared_ptr system_resource_limit; @@ -337,6 +339,14 @@ const Kernel::Synchronization& KernelCore::Synchronization() const { return impl->synchronization; } +Kernel::TimeManager& KernelCore::TimeManager() { + return impl->time_manager; +} + +const Kernel::TimeManager& KernelCore::TimeManager() const { + return impl->time_manager; +} + Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { return *impl->exclusive_monitor; } -- cgit v1.2.3 From d219a96cc828d17932beebead209ba696b92a911 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 22 Feb 2020 10:27:40 -0400 Subject: Kernel: Address Feedback. --- src/core/hle/kernel/kernel.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index de14e1936..9232f4d7e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include @@ -17,6 +18,7 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/core_timing_util.h" +#include "core/hardware_properties.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" @@ -188,6 +190,7 @@ struct KernelCore::Impl { } void RegisterCoreThread(std::size_t core_id) { + std::unique_lock lock{register_thread_mutex}; const std::thread::id this_id = std::this_thread::get_id(); const auto it = host_thread_ids.find(this_id); ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); @@ -198,13 +201,14 @@ struct KernelCore::Impl { } void RegisterHostThread() { + std::unique_lock lock{register_thread_mutex}; const std::thread::id this_id = std::this_thread::get_id(); const auto it = host_thread_ids.find(this_id); ASSERT(it == host_thread_ids.end()); host_thread_ids[this_id] = registered_thread_ids++; } - u32 GetCurrentHostThreadId() const { + u32 GetCurrentHostThreadID() const { const std::thread::id this_id = std::this_thread::get_id(); const auto it = host_thread_ids.find(this_id); if (it == host_thread_ids.end()) { @@ -213,9 +217,9 @@ struct KernelCore::Impl { return it->second; } - Core::EmuThreadHandle GetCurrentEmuThreadId() const { + Core::EmuThreadHandle GetCurrentEmuThreadID() const { Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); - result.host_handle = GetCurrentHostThreadId(); + result.host_handle = GetCurrentHostThreadID(); if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { return result; } @@ -246,8 +250,8 @@ struct KernelCore::Impl { std::shared_ptr thread_wakeup_event_type; std::shared_ptr preemption_event; - // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, - // allowing us to simply use a pool index or similar. + // This is the kernel's handle table or supervisor handle table which + // stores all the objects in place. Kernel::HandleTable global_handle_table; /// Map of named ports managed by the kernel, which can be retrieved using @@ -257,10 +261,11 @@ struct KernelCore::Impl { std::unique_ptr exclusive_monitor; std::vector cores; - // 0-3 Ids represent core threads, >3 represent others + // 0-3 IDs represent core threads, >3 represent others std::unordered_map host_thread_ids; u32 registered_thread_ids{Core::Hardware::NUM_CPU_CORES}; - std::bitset registered_core_threads{}; + std::bitset registered_core_threads; + std::mutex register_thread_mutex; // System context Core::System& system; @@ -420,12 +425,12 @@ void KernelCore::RegisterHostThread() { impl->RegisterHostThread(); } -u32 KernelCore::GetCurrentHostThreadId() const { - return impl->GetCurrentHostThreadId(); +u32 KernelCore::GetCurrentHostThreadID() const { + return impl->GetCurrentHostThreadID(); } -Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadId() const { - return impl->GetCurrentEmuThreadId(); +Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const { + return impl->GetCurrentEmuThreadID(); } } // namespace Kernel -- cgit v1.2.3