From 1f99f5473c7a03c791ea20256c7fc2f1caba8adc Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 19 Jan 2021 21:07:07 -0800 Subject: kernel: k_light_lock: Simplify EmuThreadHandle implementation. --- src/core/hardware_properties.h | 36 ++++++++-------------------------- src/core/hle/kernel/k_light_lock.cpp | 12 +++++++++--- src/core/hle/kernel/k_scheduler_lock.h | 9 ++++----- src/core/hle/kernel/kernel.cpp | 21 +++++++------------- src/core/hle/kernel/kernel.h | 6 +++++- 5 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h index 456b41e1b..176a72c67 100644 --- a/src/core/hardware_properties.h +++ b/src/core/hardware_properties.h @@ -4,8 +4,10 @@ #pragma once +#include #include +#include "common/bit_util.h" #include "common/common_types.h" namespace Core { @@ -18,34 +20,12 @@ constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch cpu frequency is 1020MHz u constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores -} // namespace Hardware - -constexpr u32 INVALID_HOST_THREAD_ID = 0xFFFFFFFF; - -struct EmuThreadHandle { - u32 host_handle; - u32 guest_handle; - - u64 GetRaw() const { - return (static_cast(host_handle) << 32) | guest_handle; - } - - bool operator==(const EmuThreadHandle& rhs) const { - return std::tie(host_handle, guest_handle) == std::tie(rhs.host_handle, rhs.guest_handle); - } - - bool operator!=(const EmuThreadHandle& rhs) const { - return !operator==(rhs); - } - - static constexpr EmuThreadHandle InvalidHandle() { - constexpr u32 invalid_handle = 0xFFFFFFFF; - return {invalid_handle, invalid_handle}; - } - - bool IsInvalid() const { - return (*this) == InvalidHandle(); - } +// Virtual to Physical core map. +constexpr std::array()> VirtualToPhysicalCoreMap{ + 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, }; +} // namespace Hardware + } // namespace Core diff --git a/src/core/hle/kernel/k_light_lock.cpp b/src/core/hle/kernel/k_light_lock.cpp index 08fa65fd5..1d54ba5df 100644 --- a/src/core/hle/kernel/k_light_lock.cpp +++ b/src/core/hle/kernel/k_light_lock.cpp @@ -9,6 +9,12 @@ namespace Kernel { +static KThread* ToThread(uintptr_t thread_) { + ASSERT((thread_ & EmuThreadHandleReserved) == 0); + ASSERT((thread_ & 1) == 0); + return reinterpret_cast(thread_); +} + void KLightLock::Lock() { const uintptr_t cur_thread = reinterpret_cast(GetCurrentThreadPointer(kernel)); const uintptr_t cur_thread_tag = (cur_thread | 1); @@ -42,7 +48,7 @@ void KLightLock::Unlock() { } void KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) { - KThread* cur_thread = reinterpret_cast(_cur_thread); + KThread* cur_thread = ToThread(_cur_thread); // Pend the current thread waiting on the owner thread. { @@ -54,7 +60,7 @@ void KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) { } // Add the current thread as a waiter on the owner. - KThread* owner_thread = reinterpret_cast(_owner & ~1ul); + KThread* owner_thread = ToThread(_owner & ~1ul); cur_thread->SetAddressKey(reinterpret_cast(std::addressof(tag))); owner_thread->AddWaiter(cur_thread); @@ -82,7 +88,7 @@ void KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) { } void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) { - KThread* owner_thread = reinterpret_cast(_cur_thread); + KThread* owner_thread = ToThread(_cur_thread); // Unlock. { diff --git a/src/core/hle/kernel/k_scheduler_lock.h b/src/core/hle/kernel/k_scheduler_lock.h index 9b40bd22c..5d48dcf38 100644 --- a/src/core/hle/kernel/k_scheduler_lock.h +++ b/src/core/hle/kernel/k_scheduler_lock.h @@ -37,7 +37,7 @@ public: // For debug, ensure that our state is valid. ASSERT(this->lock_count == 0); - ASSERT(this->owner_thread == Core::EmuThreadHandle::InvalidHandle()); + ASSERT(this->owner_thread == EmuThreadHandleInvalid); // Increment count, take ownership. this->lock_count = 1; @@ -54,14 +54,13 @@ public: // We're no longer going to hold the lock. Take note of what cores need scheduling. const u64 cores_needing_scheduling = SchedulerType::UpdateHighestPriorityThreads(kernel); - Core::EmuThreadHandle leaving_thread = owner_thread; // Note that we no longer hold the lock, and unlock the spinlock. - this->owner_thread = Core::EmuThreadHandle::InvalidHandle(); + this->owner_thread = EmuThreadHandleInvalid; this->spin_lock.unlock(); // Enable scheduling, and perform a rescheduling operation. - SchedulerType::EnableScheduling(kernel, cores_needing_scheduling, leaving_thread); + SchedulerType::EnableScheduling(kernel, cores_needing_scheduling); } } @@ -69,7 +68,7 @@ private: KernelCore& kernel; Common::SpinLock spin_lock{}; s32 lock_count{}; - Core::EmuThreadHandle owner_thread{Core::EmuThreadHandle::InvalidHandle()}; + EmuThreadHandle owner_thread{EmuThreadHandleInvalid}; }; } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 97a5dc2e0..39d5122f5 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -237,20 +237,13 @@ struct KernelCore::Impl { is_phantom_mode_for_singlecore = value; } - [[nodiscard]] Core::EmuThreadHandle GetCurrentEmuThreadID() { - Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); - result.host_handle = GetCurrentHostThreadID(); - if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { - return result; + [[nodiscard]] EmuThreadHandle GetCurrentEmuThreadID() { + const auto thread_id = GetCurrentHostThreadID(); + if (thread_id >= Core::Hardware::NUM_CPU_CORES) { + // Reserved value for HLE threads + return EmuThreadHandleReserved + (static_cast(thread_id) << 1); } - const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler(); - const Kernel::KThread* current = sched.GetCurrentThread(); - if (current != nullptr && !IsPhantomModeForSingleCore()) { - result.guest_handle = current->GetGlobalHandle(); - } else { - result.guest_handle = InvalidHandle; - } - return result; + return reinterpret_cast(schedulers[thread_id].get()); } void InitializeMemoryLayout() { @@ -555,7 +548,7 @@ u32 KernelCore::GetCurrentHostThreadID() const { return impl->GetCurrentHostThreadID(); } -Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const { +EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const { return impl->GetCurrentEmuThreadID(); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index fc58f3ecb..b92c017f6 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -46,6 +46,10 @@ class Synchronization; class KThread; class TimeManager; +using EmuThreadHandle = uintptr_t; +constexpr EmuThreadHandle EmuThreadHandleInvalid{}; +constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63}; + /// Represents a single instance of the kernel. class KernelCore { private: @@ -162,7 +166,7 @@ public: bool IsValidNamedPort(NamedPortTable::const_iterator port) const; /// Gets the current host_thread/guest_thread handle. - Core::EmuThreadHandle GetCurrentEmuThreadID() const; + EmuThreadHandle GetCurrentEmuThreadID() const; /// Gets the current host_thread handle. u32 GetCurrentHostThreadID() const; -- cgit v1.2.3