summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2021-01-19 21:07:07 -0800
committerGravatar bunnei2021-01-28 21:42:26 -0800
commit1f99f5473c7a03c791ea20256c7fc2f1caba8adc (patch)
tree3dea03c0082e6685aeda2769fd7b186f0afbf46c
parenthle: kernel: TimeManager: Simplify to not rely on previous EmuThreadHandle im... (diff)
downloadyuzu-1f99f5473c7a03c791ea20256c7fc2f1caba8adc.tar.gz
yuzu-1f99f5473c7a03c791ea20256c7fc2f1caba8adc.tar.xz
yuzu-1f99f5473c7a03c791ea20256c7fc2f1caba8adc.zip
kernel: k_light_lock: Simplify EmuThreadHandle implementation.
-rw-r--r--src/core/hardware_properties.h36
-rw-r--r--src/core/hle/kernel/k_light_lock.cpp12
-rw-r--r--src/core/hle/kernel/k_scheduler_lock.h9
-rw-r--r--src/core/hle/kernel/kernel.cpp21
-rw-r--r--src/core/hle/kernel/kernel.h6
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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <tuple> 8#include <tuple>
8 9
10#include "common/bit_util.h"
9#include "common/common_types.h" 11#include "common/common_types.h"
10 12
11namespace Core { 13namespace Core {
@@ -18,34 +20,12 @@ constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch cpu frequency is 1020MHz u
18constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed 20constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed
19constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores 21constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores
20 22
21} // namespace Hardware 23// Virtual to Physical core map.
22 24constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{
23constexpr u32 INVALID_HOST_THREAD_ID = 0xFFFFFFFF; 25 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,
24 26 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,
25struct EmuThreadHandle {
26 u32 host_handle;
27 u32 guest_handle;
28
29 u64 GetRaw() const {
30 return (static_cast<u64>(host_handle) << 32) | guest_handle;
31 }
32
33 bool operator==(const EmuThreadHandle& rhs) const {
34 return std::tie(host_handle, guest_handle) == std::tie(rhs.host_handle, rhs.guest_handle);
35 }
36
37 bool operator!=(const EmuThreadHandle& rhs) const {
38 return !operator==(rhs);
39 }
40
41 static constexpr EmuThreadHandle InvalidHandle() {
42 constexpr u32 invalid_handle = 0xFFFFFFFF;
43 return {invalid_handle, invalid_handle};
44 }
45
46 bool IsInvalid() const {
47 return (*this) == InvalidHandle();
48 }
49}; 27};
50 28
29} // namespace Hardware
30
51} // namespace Core 31} // 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 @@
9 9
10namespace Kernel { 10namespace Kernel {
11 11
12static KThread* ToThread(uintptr_t thread_) {
13 ASSERT((thread_ & EmuThreadHandleReserved) == 0);
14 ASSERT((thread_ & 1) == 0);
15 return reinterpret_cast<KThread*>(thread_);
16}
17
12void KLightLock::Lock() { 18void KLightLock::Lock() {
13 const uintptr_t cur_thread = reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(kernel)); 19 const uintptr_t cur_thread = reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(kernel));
14 const uintptr_t cur_thread_tag = (cur_thread | 1); 20 const uintptr_t cur_thread_tag = (cur_thread | 1);
@@ -42,7 +48,7 @@ void KLightLock::Unlock() {
42} 48}
43 49
44void KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) { 50void KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) {
45 KThread* cur_thread = reinterpret_cast<KThread*>(_cur_thread); 51 KThread* cur_thread = ToThread(_cur_thread);
46 52
47 // Pend the current thread waiting on the owner thread. 53 // Pend the current thread waiting on the owner thread.
48 { 54 {
@@ -54,7 +60,7 @@ void KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) {
54 } 60 }
55 61
56 // Add the current thread as a waiter on the owner. 62 // Add the current thread as a waiter on the owner.
57 KThread* owner_thread = reinterpret_cast<KThread*>(_owner & ~1ul); 63 KThread* owner_thread = ToThread(_owner & ~1ul);
58 cur_thread->SetAddressKey(reinterpret_cast<uintptr_t>(std::addressof(tag))); 64 cur_thread->SetAddressKey(reinterpret_cast<uintptr_t>(std::addressof(tag)));
59 owner_thread->AddWaiter(cur_thread); 65 owner_thread->AddWaiter(cur_thread);
60 66
@@ -82,7 +88,7 @@ void KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) {
82} 88}
83 89
84void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) { 90void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) {
85 KThread* owner_thread = reinterpret_cast<KThread*>(_cur_thread); 91 KThread* owner_thread = ToThread(_cur_thread);
86 92
87 // Unlock. 93 // Unlock.
88 { 94 {
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:
37 37
38 // For debug, ensure that our state is valid. 38 // For debug, ensure that our state is valid.
39 ASSERT(this->lock_count == 0); 39 ASSERT(this->lock_count == 0);
40 ASSERT(this->owner_thread == Core::EmuThreadHandle::InvalidHandle()); 40 ASSERT(this->owner_thread == EmuThreadHandleInvalid);
41 41
42 // Increment count, take ownership. 42 // Increment count, take ownership.
43 this->lock_count = 1; 43 this->lock_count = 1;
@@ -54,14 +54,13 @@ public:
54 // We're no longer going to hold the lock. Take note of what cores need scheduling. 54 // We're no longer going to hold the lock. Take note of what cores need scheduling.
55 const u64 cores_needing_scheduling = 55 const u64 cores_needing_scheduling =
56 SchedulerType::UpdateHighestPriorityThreads(kernel); 56 SchedulerType::UpdateHighestPriorityThreads(kernel);
57 Core::EmuThreadHandle leaving_thread = owner_thread;
58 57
59 // Note that we no longer hold the lock, and unlock the spinlock. 58 // Note that we no longer hold the lock, and unlock the spinlock.
60 this->owner_thread = Core::EmuThreadHandle::InvalidHandle(); 59 this->owner_thread = EmuThreadHandleInvalid;
61 this->spin_lock.unlock(); 60 this->spin_lock.unlock();
62 61
63 // Enable scheduling, and perform a rescheduling operation. 62 // Enable scheduling, and perform a rescheduling operation.
64 SchedulerType::EnableScheduling(kernel, cores_needing_scheduling, leaving_thread); 63 SchedulerType::EnableScheduling(kernel, cores_needing_scheduling);
65 } 64 }
66 } 65 }
67 66
@@ -69,7 +68,7 @@ private:
69 KernelCore& kernel; 68 KernelCore& kernel;
70 Common::SpinLock spin_lock{}; 69 Common::SpinLock spin_lock{};
71 s32 lock_count{}; 70 s32 lock_count{};
72 Core::EmuThreadHandle owner_thread{Core::EmuThreadHandle::InvalidHandle()}; 71 EmuThreadHandle owner_thread{EmuThreadHandleInvalid};
73}; 72};
74 73
75} // namespace Kernel 74} // 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 {
237 is_phantom_mode_for_singlecore = value; 237 is_phantom_mode_for_singlecore = value;
238 } 238 }
239 239
240 [[nodiscard]] Core::EmuThreadHandle GetCurrentEmuThreadID() { 240 [[nodiscard]] EmuThreadHandle GetCurrentEmuThreadID() {
241 Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); 241 const auto thread_id = GetCurrentHostThreadID();
242 result.host_handle = GetCurrentHostThreadID(); 242 if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
243 if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { 243 // Reserved value for HLE threads
244 return result; 244 return EmuThreadHandleReserved + (static_cast<u64>(thread_id) << 1);
245 } 245 }
246 const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler(); 246 return reinterpret_cast<uintptr_t>(schedulers[thread_id].get());
247 const Kernel::KThread* current = sched.GetCurrentThread();
248 if (current != nullptr && !IsPhantomModeForSingleCore()) {
249 result.guest_handle = current->GetGlobalHandle();
250 } else {
251 result.guest_handle = InvalidHandle;
252 }
253 return result;
254 } 247 }
255 248
256 void InitializeMemoryLayout() { 249 void InitializeMemoryLayout() {
@@ -555,7 +548,7 @@ u32 KernelCore::GetCurrentHostThreadID() const {
555 return impl->GetCurrentHostThreadID(); 548 return impl->GetCurrentHostThreadID();
556} 549}
557 550
558Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const { 551EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const {
559 return impl->GetCurrentEmuThreadID(); 552 return impl->GetCurrentEmuThreadID();
560} 553}
561 554
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;
46class KThread; 46class KThread;
47class TimeManager; 47class TimeManager;
48 48
49using EmuThreadHandle = uintptr_t;
50constexpr EmuThreadHandle EmuThreadHandleInvalid{};
51constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63};
52
49/// Represents a single instance of the kernel. 53/// Represents a single instance of the kernel.
50class KernelCore { 54class KernelCore {
51private: 55private:
@@ -162,7 +166,7 @@ public:
162 bool IsValidNamedPort(NamedPortTable::const_iterator port) const; 166 bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
163 167
164 /// Gets the current host_thread/guest_thread handle. 168 /// Gets the current host_thread/guest_thread handle.
165 Core::EmuThreadHandle GetCurrentEmuThreadID() const; 169 EmuThreadHandle GetCurrentEmuThreadID() const;
166 170
167 /// Gets the current host_thread handle. 171 /// Gets the current host_thread handle.
168 u32 GetCurrentHostThreadID() const; 172 u32 GetCurrentHostThreadID() const;