summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/fiber.cpp117
-rw-r--r--src/common/fiber.h9
-rw-r--r--src/core/arm/arm_interface.h22
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp11
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp11
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h2
-rw-r--r--src/core/core.cpp17
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/cpu_manager.cpp16
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp6
-rw-r--r--src/core/hle/kernel/address_arbiter.h3
-rw-r--r--src/core/hle/kernel/kernel.cpp28
-rw-r--r--src/core/hle/kernel/kernel.h5
-rw-r--r--src/core/hle/kernel/memory/page_table.cpp5
-rw-r--r--src/core/hle/kernel/physical_core.cpp38
-rw-r--r--src/core/hle/kernel/physical_core.h33
-rw-r--r--src/core/hle/kernel/scheduler.cpp66
-rw-r--r--src/core/hle/kernel/scheduler.h2
-rw-r--r--src/core/hle/kernel/svc.cpp9
-rw-r--r--src/core/hle/kernel/synchronization_object.h3
-rw-r--r--src/core/hle/kernel/thread.cpp32
-rw-r--r--src/core/hle/kernel/thread.h6
-rw-r--r--src/core/hle/kernel/time_manager.cpp9
-rw-r--r--src/core/hle/kernel/time_manager.h2
-rw-r--r--src/core/hle/service/ldr/ldr.cpp5
-rw-r--r--src/input_common/mouse/mouse_input.cpp38
-rw-r--r--src/input_common/mouse/mouse_input.h9
-rw-r--r--src/input_common/mouse/mouse_poller.cpp4
-rw-r--r--src/video_core/command_classes/codecs/vp9.cpp20
-rw-r--r--src/video_core/command_classes/vic.cpp2
-rw-r--r--src/yuzu/debugger/wait_tree.cpp24
32 files changed, 250 insertions, 308 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index 3e3029cd1..3c1eefcb7 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -5,18 +5,20 @@
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/fiber.h" 6#include "common/fiber.h"
7#include "common/spin_lock.h" 7#include "common/spin_lock.h"
8#include "common/virtual_buffer.h"
8 9
9#if defined(_WIN32) || defined(WIN32)
10#include <windows.h>
11#else
12#include <boost/context/detail/fcontext.hpp> 10#include <boost/context/detail/fcontext.hpp>
13#endif
14 11
15namespace Common { 12namespace Common {
16 13
17constexpr std::size_t default_stack_size = 256 * 1024; // 256kb 14constexpr std::size_t default_stack_size = 256 * 1024;
18 15
19struct Fiber::FiberImpl { 16struct Fiber::FiberImpl {
17 FiberImpl() : stack{default_stack_size}, rewind_stack{default_stack_size} {}
18
19 VirtualBuffer<u8> stack;
20 VirtualBuffer<u8> rewind_stack;
21
20 SpinLock guard{}; 22 SpinLock guard{};
21 std::function<void(void*)> entry_point; 23 std::function<void(void*)> entry_point;
22 std::function<void(void*)> rewind_point; 24 std::function<void(void*)> rewind_point;
@@ -26,17 +28,10 @@ struct Fiber::FiberImpl {
26 bool is_thread_fiber{}; 28 bool is_thread_fiber{};
27 bool released{}; 29 bool released{};
28 30
29#if defined(_WIN32) || defined(WIN32) 31 u8* stack_limit{};
30 LPVOID handle = nullptr; 32 u8* rewind_stack_limit{};
31 LPVOID rewind_handle = nullptr; 33 boost::context::detail::fcontext_t context{};
32#else 34 boost::context::detail::fcontext_t rewind_context{};
33 alignas(64) std::array<u8, default_stack_size> stack;
34 alignas(64) std::array<u8, default_stack_size> rewind_stack;
35 u8* stack_limit;
36 u8* rewind_stack_limit;
37 boost::context::detail::fcontext_t context;
38 boost::context::detail::fcontext_t rewind_context;
39#endif
40}; 35};
41 36
42void Fiber::SetStartParameter(void* new_parameter) { 37void Fiber::SetStartParameter(void* new_parameter) {
@@ -48,95 +43,6 @@ void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewin
48 impl->rewind_parameter = rewind_param; 43 impl->rewind_parameter = rewind_param;
49} 44}
50 45
51#if defined(_WIN32) || defined(WIN32)
52
53void Fiber::Start() {
54 ASSERT(impl->previous_fiber != nullptr);
55 impl->previous_fiber->impl->guard.unlock();
56 impl->previous_fiber.reset();
57 impl->entry_point(impl->start_parameter);
58 UNREACHABLE();
59}
60
61void Fiber::OnRewind() {
62 ASSERT(impl->handle != nullptr);
63 DeleteFiber(impl->handle);
64 impl->handle = impl->rewind_handle;
65 impl->rewind_handle = nullptr;
66 impl->rewind_point(impl->rewind_parameter);
67 UNREACHABLE();
68}
69
70void Fiber::FiberStartFunc(void* fiber_parameter) {
71 auto* fiber = static_cast<Fiber*>(fiber_parameter);
72 fiber->Start();
73}
74
75void Fiber::RewindStartFunc(void* fiber_parameter) {
76 auto* fiber = static_cast<Fiber*>(fiber_parameter);
77 fiber->OnRewind();
78}
79
80Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter)
81 : impl{std::make_unique<FiberImpl>()} {
82 impl->entry_point = std::move(entry_point_func);
83 impl->start_parameter = start_parameter;
84 impl->handle = CreateFiber(default_stack_size, &FiberStartFunc, this);
85}
86
87Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {}
88
89Fiber::~Fiber() {
90 if (impl->released) {
91 return;
92 }
93 // Make sure the Fiber is not being used
94 const bool locked = impl->guard.try_lock();
95 ASSERT_MSG(locked, "Destroying a fiber that's still running");
96 if (locked) {
97 impl->guard.unlock();
98 }
99 DeleteFiber(impl->handle);
100}
101
102void Fiber::Exit() {
103 ASSERT_MSG(impl->is_thread_fiber, "Exitting non main thread fiber");
104 if (!impl->is_thread_fiber) {
105 return;
106 }
107 ConvertFiberToThread();
108 impl->guard.unlock();
109 impl->released = true;
110}
111
112void Fiber::Rewind() {
113 ASSERT(impl->rewind_point);
114 ASSERT(impl->rewind_handle == nullptr);
115 impl->rewind_handle = CreateFiber(default_stack_size, &RewindStartFunc, this);
116 SwitchToFiber(impl->rewind_handle);
117}
118
119void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) {
120 ASSERT_MSG(from != nullptr, "Yielding fiber is null!");
121 ASSERT_MSG(to != nullptr, "Next fiber is null!");
122 to->impl->guard.lock();
123 to->impl->previous_fiber = from;
124 SwitchToFiber(to->impl->handle);
125 ASSERT(from->impl->previous_fiber != nullptr);
126 from->impl->previous_fiber->impl->guard.unlock();
127 from->impl->previous_fiber.reset();
128}
129
130std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
131 std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()};
132 fiber->impl->guard.lock();
133 fiber->impl->handle = ConvertThreadToFiber(nullptr);
134 fiber->impl->is_thread_fiber = true;
135 return fiber;
136}
137
138#else
139
140void Fiber::Start(boost::context::detail::transfer_t& transfer) { 46void Fiber::Start(boost::context::detail::transfer_t& transfer) {
141 ASSERT(impl->previous_fiber != nullptr); 47 ASSERT(impl->previous_fiber != nullptr);
142 impl->previous_fiber->impl->context = transfer.fctx; 48 impl->previous_fiber->impl->context = transfer.fctx;
@@ -229,5 +135,4 @@ std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
229 return fiber; 135 return fiber;
230} 136}
231 137
232#endif
233} // namespace Common 138} // namespace Common
diff --git a/src/common/fiber.h b/src/common/fiber.h
index 5323e8579..f7f587f8c 100644
--- a/src/common/fiber.h
+++ b/src/common/fiber.h
@@ -7,11 +7,9 @@
7#include <functional> 7#include <functional>
8#include <memory> 8#include <memory>
9 9
10#if !defined(_WIN32) && !defined(WIN32)
11namespace boost::context::detail { 10namespace boost::context::detail {
12struct transfer_t; 11struct transfer_t;
13} 12}
14#endif
15 13
16namespace Common { 14namespace Common {
17 15
@@ -59,17 +57,10 @@ public:
59private: 57private:
60 Fiber(); 58 Fiber();
61 59
62#if defined(_WIN32) || defined(WIN32)
63 void OnRewind();
64 void Start();
65 static void FiberStartFunc(void* fiber_parameter);
66 static void RewindStartFunc(void* fiber_parameter);
67#else
68 void OnRewind(boost::context::detail::transfer_t& transfer); 60 void OnRewind(boost::context::detail::transfer_t& transfer);
69 void Start(boost::context::detail::transfer_t& transfer); 61 void Start(boost::context::detail::transfer_t& transfer);
70 static void FiberStartFunc(boost::context::detail::transfer_t transfer); 62 static void FiberStartFunc(boost::context::detail::transfer_t transfer);
71 static void RewindStartFunc(boost::context::detail::transfer_t transfer); 63 static void RewindStartFunc(boost::context::detail::transfer_t transfer);
72#endif
73 64
74 struct FiberImpl; 65 struct FiberImpl;
75 std::unique_ptr<FiberImpl> impl; 66 std::unique_ptr<FiberImpl> impl;
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 1f24051e4..70098c526 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -64,15 +64,25 @@ public:
64 /// Step CPU by one instruction 64 /// Step CPU by one instruction
65 virtual void Step() = 0; 65 virtual void Step() = 0;
66 66
67 /// Exits execution from a callback, the callback must rewind the stack
68 virtual void ExceptionalExit() = 0;
69
67 /// Clear all instruction cache 70 /// Clear all instruction cache
68 virtual void ClearInstructionCache() = 0; 71 virtual void ClearInstructionCache() = 0;
69 72
70 /// Notifies CPU emulation that the current page table has changed. 73 /**
71 /// 74 * Clear instruction cache range
72 /// @param new_page_table The new page table. 75 * @param addr Start address of the cache range to clear
73 /// @param new_address_space_size_in_bits The new usable size of the address space in bits. 76 * @param size Size of the cache range to clear, starting at addr
74 /// This can be either 32, 36, or 39 on official software. 77 */
75 /// 78 virtual void InvalidateCacheRange(VAddr addr, std::size_t size) = 0;
79
80 /**
81 * Notifies CPU emulation that the current page table has changed.
82 * @param new_page_table The new page table.
83 * @param new_address_space_size_in_bits The new usable size of the address space in bits.
84 * This can be either 32, 36, or 39 on official software.
85 */
76 virtual void PageTableChanged(Common::PageTable& new_page_table, 86 virtual void PageTableChanged(Common::PageTable& new_page_table,
77 std::size_t new_address_space_size_in_bits) = 0; 87 std::size_t new_address_space_size_in_bits) = 0;
78 88
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 6dc03f3b1..193fd7d62 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -189,6 +189,10 @@ void ARM_Dynarmic_32::Run() {
189 jit->Run(); 189 jit->Run();
190} 190}
191 191
192void ARM_Dynarmic_32::ExceptionalExit() {
193 jit->ExceptionalExit();
194}
195
192void ARM_Dynarmic_32::Step() { 196void ARM_Dynarmic_32::Step() {
193 jit->Step(); 197 jit->Step();
194} 198}
@@ -282,6 +286,13 @@ void ARM_Dynarmic_32::ClearInstructionCache() {
282 jit->ClearCache(); 286 jit->ClearCache();
283} 287}
284 288
289void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) {
290 if (!jit) {
291 return;
292 }
293 jit->InvalidateCacheRange(static_cast<u32>(addr), size);
294}
295
285void ARM_Dynarmic_32::ClearExclusiveState() { 296void ARM_Dynarmic_32::ClearExclusiveState() {
286 jit->ClearExclusiveState(); 297 jit->ClearExclusiveState();
287} 298}
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index 2bab31b92..35e9ced48 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -42,6 +42,7 @@ public:
42 u32 GetPSTATE() const override; 42 u32 GetPSTATE() const override;
43 void SetPSTATE(u32 pstate) override; 43 void SetPSTATE(u32 pstate) override;
44 void Run() override; 44 void Run() override;
45 void ExceptionalExit() override;
45 void Step() override; 46 void Step() override;
46 VAddr GetTlsAddress() const override; 47 VAddr GetTlsAddress() const override;
47 void SetTlsAddress(VAddr address) override; 48 void SetTlsAddress(VAddr address) override;
@@ -58,6 +59,7 @@ public:
58 void ClearExclusiveState() override; 59 void ClearExclusiveState() override;
59 60
60 void ClearInstructionCache() override; 61 void ClearInstructionCache() override;
62 void InvalidateCacheRange(VAddr addr, std::size_t size) override;
61 void PageTableChanged(Common::PageTable& new_page_table, 63 void PageTableChanged(Common::PageTable& new_page_table,
62 std::size_t new_address_space_size_in_bits) override; 64 std::size_t new_address_space_size_in_bits) override;
63 65
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 5c2060d78..0f0585d0f 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -220,6 +220,10 @@ void ARM_Dynarmic_64::Run() {
220 jit->Run(); 220 jit->Run();
221} 221}
222 222
223void ARM_Dynarmic_64::ExceptionalExit() {
224 jit->ExceptionalExit();
225}
226
223void ARM_Dynarmic_64::Step() { 227void ARM_Dynarmic_64::Step() {
224 cb->InterpreterFallback(jit->GetPC(), 1); 228 cb->InterpreterFallback(jit->GetPC(), 1);
225} 229}
@@ -318,6 +322,13 @@ void ARM_Dynarmic_64::ClearInstructionCache() {
318 jit->ClearCache(); 322 jit->ClearCache();
319} 323}
320 324
325void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) {
326 if (!jit) {
327 return;
328 }
329 jit->InvalidateCacheRange(addr, size);
330}
331
321void ARM_Dynarmic_64::ClearExclusiveState() { 332void ARM_Dynarmic_64::ClearExclusiveState() {
322 jit->ClearExclusiveState(); 333 jit->ClearExclusiveState();
323} 334}
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 28e11a17d..329b59a32 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -40,6 +40,7 @@ public:
40 void SetPSTATE(u32 pstate) override; 40 void SetPSTATE(u32 pstate) override;
41 void Run() override; 41 void Run() override;
42 void Step() override; 42 void Step() override;
43 void ExceptionalExit() override;
43 VAddr GetTlsAddress() const override; 44 VAddr GetTlsAddress() const override;
44 void SetTlsAddress(VAddr address) override; 45 void SetTlsAddress(VAddr address) override;
45 void SetTPIDR_EL0(u64 value) override; 46 void SetTPIDR_EL0(u64 value) override;
@@ -55,6 +56,7 @@ public:
55 void ClearExclusiveState() override; 56 void ClearExclusiveState() override;
56 57
57 void ClearInstructionCache() override; 58 void ClearInstructionCache() override;
59 void InvalidateCacheRange(VAddr addr, std::size_t size) override;
58 void PageTableChanged(Common::PageTable& new_page_table, 60 void PageTableChanged(Common::PageTable& new_page_table,
59 std::size_t new_address_space_size_in_bits) override; 61 std::size_t new_address_space_size_in_bits) override;
60 62
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 76a38ea2a..01e4faac8 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -245,6 +245,7 @@ struct System::Impl {
245 } 245 }
246 AddGlueRegistrationForProcess(*app_loader, *main_process); 246 AddGlueRegistrationForProcess(*app_loader, *main_process);
247 kernel.MakeCurrentProcess(main_process.get()); 247 kernel.MakeCurrentProcess(main_process.get());
248 kernel.InitializeCores();
248 249
249 // Initialize cheat engine 250 // Initialize cheat engine
250 if (cheat_engine) { 251 if (cheat_engine) {
@@ -456,6 +457,10 @@ void System::InvalidateCpuInstructionCaches() {
456 impl->kernel.InvalidateAllInstructionCaches(); 457 impl->kernel.InvalidateAllInstructionCaches();
457} 458}
458 459
460void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
461 impl->kernel.InvalidateCpuInstructionCacheRange(addr, size);
462}
463
459void System::Shutdown() { 464void System::Shutdown() {
460 impl->Shutdown(); 465 impl->Shutdown();
461} 466}
@@ -490,11 +495,11 @@ const TelemetrySession& System::TelemetrySession() const {
490} 495}
491 496
492ARM_Interface& System::CurrentArmInterface() { 497ARM_Interface& System::CurrentArmInterface() {
493 return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); 498 return impl->kernel.CurrentPhysicalCore().ArmInterface();
494} 499}
495 500
496const ARM_Interface& System::CurrentArmInterface() const { 501const ARM_Interface& System::CurrentArmInterface() const {
497 return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); 502 return impl->kernel.CurrentPhysicalCore().ArmInterface();
498} 503}
499 504
500std::size_t System::CurrentCoreIndex() const { 505std::size_t System::CurrentCoreIndex() const {
@@ -554,15 +559,11 @@ const Kernel::Process* System::CurrentProcess() const {
554} 559}
555 560
556ARM_Interface& System::ArmInterface(std::size_t core_index) { 561ARM_Interface& System::ArmInterface(std::size_t core_index) {
557 auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread(); 562 return impl->kernel.PhysicalCore(core_index).ArmInterface();
558 ASSERT(thread && !thread->IsHLEThread());
559 return thread->ArmInterface();
560} 563}
561 564
562const ARM_Interface& System::ArmInterface(std::size_t core_index) const { 565const ARM_Interface& System::ArmInterface(std::size_t core_index) const {
563 auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread(); 566 return impl->kernel.PhysicalCore(core_index).ArmInterface();
564 ASSERT(thread && !thread->IsHLEThread());
565 return thread->ArmInterface();
566} 567}
567 568
568ExclusiveMonitor& System::Monitor() { 569ExclusiveMonitor& System::Monitor() {
diff --git a/src/core/core.h b/src/core/core.h
index f642befc0..29b8fb92a 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -166,6 +166,8 @@ public:
166 */ 166 */
167 void InvalidateCpuInstructionCaches(); 167 void InvalidateCpuInstructionCaches();
168 168
169 void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
170
169 /// Shutdown the emulated system. 171 /// Shutdown the emulated system.
170 void Shutdown(); 172 void Shutdown();
171 173
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index eeeb6e8df..0cff985e9 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -113,22 +113,23 @@ void CpuManager::MultiCoreRunGuestThread() {
113 auto& sched = kernel.CurrentScheduler(); 113 auto& sched = kernel.CurrentScheduler();
114 sched.OnThreadStart(); 114 sched.OnThreadStart();
115 } 115 }
116 auto* thread = kernel.CurrentScheduler().GetCurrentThread();
117 auto& host_context = thread->GetHostContext();
118 host_context->SetRewindPoint(GuestRewindFunction, this);
116 MultiCoreRunGuestLoop(); 119 MultiCoreRunGuestLoop();
117} 120}
118 121
119void CpuManager::MultiCoreRunGuestLoop() { 122void CpuManager::MultiCoreRunGuestLoop() {
120 auto& kernel = system.Kernel(); 123 auto& kernel = system.Kernel();
121 auto* thread = kernel.CurrentScheduler().GetCurrentThread(); 124
122 while (true) { 125 while (true) {
123 auto* physical_core = &kernel.CurrentPhysicalCore(); 126 auto* physical_core = &kernel.CurrentPhysicalCore();
124 auto& arm_interface = thread->ArmInterface();
125 system.EnterDynarmicProfile(); 127 system.EnterDynarmicProfile();
126 while (!physical_core->IsInterrupted()) { 128 while (!physical_core->IsInterrupted()) {
127 arm_interface.Run(); 129 physical_core->Run();
128 physical_core = &kernel.CurrentPhysicalCore(); 130 physical_core = &kernel.CurrentPhysicalCore();
129 } 131 }
130 system.ExitDynarmicProfile(); 132 system.ExitDynarmicProfile();
131 arm_interface.ClearExclusiveState();
132 auto& scheduler = kernel.CurrentScheduler(); 133 auto& scheduler = kernel.CurrentScheduler();
133 scheduler.TryDoContextSwitch(); 134 scheduler.TryDoContextSwitch();
134 } 135 }
@@ -209,6 +210,9 @@ void CpuManager::SingleCoreRunGuestThread() {
209 auto& sched = kernel.CurrentScheduler(); 210 auto& sched = kernel.CurrentScheduler();
210 sched.OnThreadStart(); 211 sched.OnThreadStart();
211 } 212 }
213 auto* thread = kernel.CurrentScheduler().GetCurrentThread();
214 auto& host_context = thread->GetHostContext();
215 host_context->SetRewindPoint(GuestRewindFunction, this);
212 SingleCoreRunGuestLoop(); 216 SingleCoreRunGuestLoop();
213} 217}
214 218
@@ -217,17 +221,15 @@ void CpuManager::SingleCoreRunGuestLoop() {
217 auto* thread = kernel.CurrentScheduler().GetCurrentThread(); 221 auto* thread = kernel.CurrentScheduler().GetCurrentThread();
218 while (true) { 222 while (true) {
219 auto* physical_core = &kernel.CurrentPhysicalCore(); 223 auto* physical_core = &kernel.CurrentPhysicalCore();
220 auto& arm_interface = thread->ArmInterface();
221 system.EnterDynarmicProfile(); 224 system.EnterDynarmicProfile();
222 if (!physical_core->IsInterrupted()) { 225 if (!physical_core->IsInterrupted()) {
223 arm_interface.Run(); 226 physical_core->Run();
224 physical_core = &kernel.CurrentPhysicalCore(); 227 physical_core = &kernel.CurrentPhysicalCore();
225 } 228 }
226 system.ExitDynarmicProfile(); 229 system.ExitDynarmicProfile();
227 thread->SetPhantomMode(true); 230 thread->SetPhantomMode(true);
228 system.CoreTiming().Advance(); 231 system.CoreTiming().Advance();
229 thread->SetPhantomMode(false); 232 thread->SetPhantomMode(false);
230 arm_interface.ClearExclusiveState();
231 PreemptSingleCore(); 233 PreemptSingleCore();
232 auto& scheduler = kernel.Scheduler(current_core); 234 auto& scheduler = kernel.Scheduler(current_core);
233 scheduler.TryDoContextSwitch(); 235 scheduler.TryDoContextSwitch();
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index b882eaa0f..048acd30e 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -275,12 +275,6 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
275 return current_thread->GetSignalingResult(); 275 return current_thread->GetSignalingResult();
276} 276}
277 277
278void AddressArbiter::HandleWakeupThread(std::shared_ptr<Thread> thread) {
279 ASSERT(thread->GetStatus() == ThreadStatus::WaitArb);
280 RemoveThread(thread);
281 thread->SetArbiterWaitAddress(0);
282}
283
284void AddressArbiter::InsertThread(std::shared_ptr<Thread> thread) { 278void AddressArbiter::InsertThread(std::shared_ptr<Thread> thread) {
285 const VAddr arb_addr = thread->GetArbiterWaitAddress(); 279 const VAddr arb_addr = thread->GetArbiterWaitAddress();
286 std::list<std::shared_ptr<Thread>>& thread_list = arb_threads[arb_addr]; 280 std::list<std::shared_ptr<Thread>>& thread_list = arb_threads[arb_addr];
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h
index 0b05d533c..b91edc67d 100644
--- a/src/core/hle/kernel/address_arbiter.h
+++ b/src/core/hle/kernel/address_arbiter.h
@@ -50,9 +50,6 @@ public:
50 /// Waits on an address with a particular arbitration type. 50 /// Waits on an address with a particular arbitration type.
51 ResultCode WaitForAddress(VAddr address, ArbitrationType type, s32 value, s64 timeout_ns); 51 ResultCode WaitForAddress(VAddr address, ArbitrationType type, s32 value, s64 timeout_ns);
52 52
53 /// Removes a thread from the container and resets its address arbiter adress to 0
54 void HandleWakeupThread(std::shared_ptr<Thread> thread);
55
56private: 53private:
57 /// Signals an address being waited on. 54 /// Signals an address being waited on.
58 ResultCode SignalToAddressOnly(VAddr address, s32 num_to_wake); 55 ResultCode SignalToAddressOnly(VAddr address, s32 num_to_wake);
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index bb3e312a7..929db696d 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -68,6 +68,12 @@ struct KernelCore::Impl {
68 InitializeSuspendThreads(); 68 InitializeSuspendThreads();
69 } 69 }
70 70
71 void InitializeCores() {
72 for (auto& core : cores) {
73 core.Initialize(current_process->Is64BitProcess());
74 }
75 }
76
71 void Shutdown() { 77 void Shutdown() {
72 next_object_id = 0; 78 next_object_id = 0;
73 next_kernel_process_id = Process::InitialKIPIDMin; 79 next_kernel_process_id = Process::InitialKIPIDMin;
@@ -116,7 +122,7 @@ struct KernelCore::Impl {
116 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); 122 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES);
117 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 123 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
118 schedulers[i] = std::make_unique<Kernel::Scheduler>(system, i); 124 schedulers[i] = std::make_unique<Kernel::Scheduler>(system, i);
119 cores.emplace_back(system, i, *schedulers[i], interrupts[i]); 125 cores.emplace_back(i, system, *schedulers[i], interrupts);
120 } 126 }
121 } 127 }
122 128
@@ -181,6 +187,7 @@ struct KernelCore::Impl {
181 if (process == nullptr) { 187 if (process == nullptr) {
182 return; 188 return;
183 } 189 }
190
184 const u32 core_id = GetCurrentHostThreadID(); 191 const u32 core_id = GetCurrentHostThreadID();
185 if (core_id < Core::Hardware::NUM_CPU_CORES) { 192 if (core_id < Core::Hardware::NUM_CPU_CORES) {
186 system.Memory().SetCurrentPageTable(*process, core_id); 193 system.Memory().SetCurrentPageTable(*process, core_id);
@@ -372,6 +379,10 @@ void KernelCore::Initialize() {
372 impl->Initialize(*this); 379 impl->Initialize(*this);
373} 380}
374 381
382void KernelCore::InitializeCores() {
383 impl->InitializeCores();
384}
385
375void KernelCore::Shutdown() { 386void KernelCore::Shutdown() {
376 impl->Shutdown(); 387 impl->Shutdown();
377} 388}
@@ -486,12 +497,17 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
486} 497}
487 498
488void KernelCore::InvalidateAllInstructionCaches() { 499void KernelCore::InvalidateAllInstructionCaches() {
489 auto& threads = GlobalScheduler().GetThreadList(); 500 for (auto& physical_core : impl->cores) {
490 for (auto& thread : threads) { 501 physical_core.ArmInterface().ClearInstructionCache();
491 if (!thread->IsHLEThread()) { 502 }
492 auto& arm_interface = thread->ArmInterface(); 503}
493 arm_interface.ClearInstructionCache(); 504
505void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
506 for (auto& physical_core : impl->cores) {
507 if (!physical_core.IsInitialized()) {
508 continue;
494 } 509 }
510 physical_core.ArmInterface().InvalidateCacheRange(addr, size);
495 } 511 }
496} 512}
497 513
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 16285c3f0..a73a93039 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -74,6 +74,9 @@ public:
74 /// Resets the kernel to a clean slate for use. 74 /// Resets the kernel to a clean slate for use.
75 void Initialize(); 75 void Initialize();
76 76
77 /// Initializes the CPU cores.
78 void InitializeCores();
79
77 /// Clears all resources in use by the kernel instance. 80 /// Clears all resources in use by the kernel instance.
78 void Shutdown(); 81 void Shutdown();
79 82
@@ -153,6 +156,8 @@ public:
153 156
154 void InvalidateAllInstructionCaches(); 157 void InvalidateAllInstructionCaches();
155 158
159 void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
160
156 /// Adds a port to the named port table 161 /// Adds a port to the named port table
157 void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port); 162 void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
158 163
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp
index a3fadb533..f53a7be82 100644
--- a/src/core/hle/kernel/memory/page_table.cpp
+++ b/src/core/hle/kernel/memory/page_table.cpp
@@ -670,6 +670,11 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo
670 return RESULT_SUCCESS; 670 return RESULT_SUCCESS;
671 } 671 }
672 672
673 if ((prev_perm & MemoryPermission::Execute) != (perm & MemoryPermission::Execute)) {
674 // Memory execution state is changing, invalidate CPU cache range
675 system.InvalidateCpuInstructionCacheRange(addr, size);
676 }
677
673 const std::size_t num_pages{size / PageSize}; 678 const std::size_t num_pages{size / PageSize};
674 const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None 679 const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None
675 ? OperationType::ChangePermissionsAndRefresh 680 ? OperationType::ChangePermissionsAndRefresh
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 6e04d025f..50aca5752 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -4,21 +4,43 @@
4 4
5#include "common/spin_lock.h" 5#include "common/spin_lock.h"
6#include "core/arm/cpu_interrupt_handler.h" 6#include "core/arm/cpu_interrupt_handler.h"
7#include "core/arm/dynarmic/arm_dynarmic_32.h"
8#include "core/arm/dynarmic/arm_dynarmic_64.h"
7#include "core/core.h" 9#include "core/core.h"
10#include "core/hle/kernel/kernel.h"
8#include "core/hle/kernel/physical_core.h" 11#include "core/hle/kernel/physical_core.h"
9#include "core/hle/kernel/scheduler.h" 12#include "core/hle/kernel/scheduler.h"
10 13
11namespace Kernel { 14namespace Kernel {
12 15
13PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler, 16PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system,
14 Core::CPUInterruptHandler& interrupt_handler) 17 Kernel::Scheduler& scheduler, Core::CPUInterrupts& interrupts)
15 : interrupt_handler{interrupt_handler}, 18 : core_index{core_index}, system{system}, scheduler{scheduler},
16 core_index{id}, scheduler{scheduler}, guard{std::make_unique<Common::SpinLock>()} {} 19 interrupts{interrupts}, guard{std::make_unique<Common::SpinLock>()} {}
17 20
18PhysicalCore::~PhysicalCore() = default; 21PhysicalCore::~PhysicalCore() = default;
19 22
23void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) {
24#ifdef ARCHITECTURE_x86_64
25 auto& kernel = system.Kernel();
26 if (is_64_bit) {
27 arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
28 system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index);
29 } else {
30 arm_interface = std::make_unique<Core::ARM_Dynarmic_32>(
31 system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index);
32 }
33#else
34#error Platform not supported yet.
35#endif
36}
37
38void PhysicalCore::Run() {
39 arm_interface->Run();
40}
41
20void PhysicalCore::Idle() { 42void PhysicalCore::Idle() {
21 interrupt_handler.AwaitInterrupt(); 43 interrupts[core_index].AwaitInterrupt();
22} 44}
23 45
24void PhysicalCore::Shutdown() { 46void PhysicalCore::Shutdown() {
@@ -26,18 +48,18 @@ void PhysicalCore::Shutdown() {
26} 48}
27 49
28bool PhysicalCore::IsInterrupted() const { 50bool PhysicalCore::IsInterrupted() const {
29 return interrupt_handler.IsInterrupted(); 51 return interrupts[core_index].IsInterrupted();
30} 52}
31 53
32void PhysicalCore::Interrupt() { 54void PhysicalCore::Interrupt() {
33 guard->lock(); 55 guard->lock();
34 interrupt_handler.SetInterrupt(true); 56 interrupts[core_index].SetInterrupt(true);
35 guard->unlock(); 57 guard->unlock();
36} 58}
37 59
38void PhysicalCore::ClearInterrupt() { 60void PhysicalCore::ClearInterrupt() {
39 guard->lock(); 61 guard->lock();
40 interrupt_handler.SetInterrupt(false); 62 interrupts[core_index].SetInterrupt(false);
41 guard->unlock(); 63 guard->unlock();
42} 64}
43 65
diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h
index d7a7a951c..37513130a 100644
--- a/src/core/hle/kernel/physical_core.h
+++ b/src/core/hle/kernel/physical_core.h
@@ -4,9 +4,12 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <cstddef> 8#include <cstddef>
8#include <memory> 9#include <memory>
9 10
11#include "core/arm/arm_interface.h"
12
10namespace Common { 13namespace Common {
11class SpinLock; 14class SpinLock;
12} 15}
@@ -16,7 +19,6 @@ class Scheduler;
16} // namespace Kernel 19} // namespace Kernel
17 20
18namespace Core { 21namespace Core {
19class ARM_Interface;
20class CPUInterruptHandler; 22class CPUInterruptHandler;
21class ExclusiveMonitor; 23class ExclusiveMonitor;
22class System; 24class System;
@@ -26,8 +28,8 @@ namespace Kernel {
26 28
27class PhysicalCore { 29class PhysicalCore {
28public: 30public:
29 PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler, 31 PhysicalCore(std::size_t core_index, Core::System& system, Kernel::Scheduler& scheduler,
30 Core::CPUInterruptHandler& interrupt_handler); 32 Core::CPUInterrupts& interrupts);
31 ~PhysicalCore(); 33 ~PhysicalCore();
32 34
33 PhysicalCore(const PhysicalCore&) = delete; 35 PhysicalCore(const PhysicalCore&) = delete;
@@ -36,7 +38,14 @@ public:
36 PhysicalCore(PhysicalCore&&) = default; 38 PhysicalCore(PhysicalCore&&) = default;
37 PhysicalCore& operator=(PhysicalCore&&) = default; 39 PhysicalCore& operator=(PhysicalCore&&) = default;
38 40
41 /// Initialize the core for the specified parameters.
42 void Initialize(bool is_64_bit);
43
44 /// Execute current jit state
45 void Run();
46
39 void Idle(); 47 void Idle();
48
40 /// Interrupt this physical core. 49 /// Interrupt this physical core.
41 void Interrupt(); 50 void Interrupt();
42 51
@@ -49,6 +58,18 @@ public:
49 // Shutdown this physical core. 58 // Shutdown this physical core.
50 void Shutdown(); 59 void Shutdown();
51 60
61 bool IsInitialized() const {
62 return arm_interface != nullptr;
63 }
64
65 Core::ARM_Interface& ArmInterface() {
66 return *arm_interface;
67 }
68
69 const Core::ARM_Interface& ArmInterface() const {
70 return *arm_interface;
71 }
72
52 bool IsMainCore() const { 73 bool IsMainCore() const {
53 return core_index == 0; 74 return core_index == 0;
54 } 75 }
@@ -70,10 +91,12 @@ public:
70 } 91 }
71 92
72private: 93private:
73 Core::CPUInterruptHandler& interrupt_handler; 94 const std::size_t core_index;
74 std::size_t core_index; 95 Core::System& system;
75 Kernel::Scheduler& scheduler; 96 Kernel::Scheduler& scheduler;
97 Core::CPUInterrupts& interrupts;
76 std::unique_ptr<Common::SpinLock> guard; 98 std::unique_ptr<Common::SpinLock> guard;
99 std::unique_ptr<Core::ARM_Interface> arm_interface;
77}; 100};
78 101
79} // namespace Kernel 102} // namespace Kernel
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 6b7db5372..5c63b0b4a 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -618,14 +618,16 @@ void Scheduler::OnThreadStart() {
618 SwitchContextStep2(); 618 SwitchContextStep2();
619} 619}
620 620
621void Scheduler::Unload() { 621void Scheduler::Unload(Thread* thread) {
622 Thread* thread = current_thread.get();
623 if (thread) { 622 if (thread) {
624 thread->SetContinuousOnSVC(false);
625 thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); 623 thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
626 thread->SetIsRunning(false); 624 thread->SetIsRunning(false);
625 if (thread->IsContinuousOnSVC() && !thread->IsHLEThread()) {
626 system.ArmInterface(core_id).ExceptionalExit();
627 thread->SetContinuousOnSVC(false);
628 }
627 if (!thread->IsHLEThread() && !thread->HasExited()) { 629 if (!thread->IsHLEThread() && !thread->HasExited()) {
628 Core::ARM_Interface& cpu_core = thread->ArmInterface(); 630 Core::ARM_Interface& cpu_core = system.ArmInterface(core_id);
629 cpu_core.SaveContext(thread->GetContext32()); 631 cpu_core.SaveContext(thread->GetContext32());
630 cpu_core.SaveContext(thread->GetContext64()); 632 cpu_core.SaveContext(thread->GetContext64());
631 // Save the TPIDR_EL0 system register in case it was modified. 633 // Save the TPIDR_EL0 system register in case it was modified.
@@ -636,8 +638,11 @@ void Scheduler::Unload() {
636 } 638 }
637} 639}
638 640
639void Scheduler::Reload() { 641void Scheduler::Unload() {
640 Thread* thread = current_thread.get(); 642 Unload(current_thread.get());
643}
644
645void Scheduler::Reload(Thread* thread) {
641 if (thread) { 646 if (thread) {
642 ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, 647 ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable,
643 "Thread must be runnable."); 648 "Thread must be runnable.");
@@ -652,42 +657,23 @@ void Scheduler::Reload() {
652 system.Kernel().MakeCurrentProcess(thread_owner_process); 657 system.Kernel().MakeCurrentProcess(thread_owner_process);
653 } 658 }
654 if (!thread->IsHLEThread()) { 659 if (!thread->IsHLEThread()) {
655 Core::ARM_Interface& cpu_core = thread->ArmInterface(); 660 Core::ARM_Interface& cpu_core = system.ArmInterface(core_id);
656 cpu_core.LoadContext(thread->GetContext32()); 661 cpu_core.LoadContext(thread->GetContext32());
657 cpu_core.LoadContext(thread->GetContext64()); 662 cpu_core.LoadContext(thread->GetContext64());
658 cpu_core.SetTlsAddress(thread->GetTLSAddress()); 663 cpu_core.SetTlsAddress(thread->GetTLSAddress());
659 cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); 664 cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0());
660 cpu_core.ChangeProcessorID(this->core_id);
661 cpu_core.ClearExclusiveState(); 665 cpu_core.ClearExclusiveState();
662 } 666 }
663 } 667 }
664} 668}
665 669
670void Scheduler::Reload() {
671 Reload(current_thread.get());
672}
673
666void Scheduler::SwitchContextStep2() { 674void Scheduler::SwitchContextStep2() {
667 // Load context of new thread 675 // Load context of new thread
668 if (selected_thread) { 676 Reload(selected_thread.get());
669 ASSERT_MSG(selected_thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable,
670 "Thread must be runnable.");
671
672 // Cancel any outstanding wakeup events for this thread
673 selected_thread->SetIsRunning(true);
674 selected_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
675 selected_thread->SetWasRunning(false);
676
677 auto* const thread_owner_process = current_thread->GetOwnerProcess();
678 if (thread_owner_process != nullptr) {
679 system.Kernel().MakeCurrentProcess(thread_owner_process);
680 }
681 if (!selected_thread->IsHLEThread()) {
682 Core::ARM_Interface& cpu_core = selected_thread->ArmInterface();
683 cpu_core.LoadContext(selected_thread->GetContext32());
684 cpu_core.LoadContext(selected_thread->GetContext64());
685 cpu_core.SetTlsAddress(selected_thread->GetTLSAddress());
686 cpu_core.SetTPIDR_EL0(selected_thread->GetTPIDR_EL0());
687 cpu_core.ChangeProcessorID(this->core_id);
688 cpu_core.ClearExclusiveState();
689 }
690 }
691 677
692 TryDoContextSwitch(); 678 TryDoContextSwitch();
693} 679}
@@ -711,23 +697,7 @@ void Scheduler::SwitchContext() {
711 UpdateLastContextSwitchTime(previous_thread, previous_process); 697 UpdateLastContextSwitchTime(previous_thread, previous_process);
712 698
713 // Save context for previous thread 699 // Save context for previous thread
714 if (previous_thread) { 700 Unload(previous_thread);
715 if (new_thread != nullptr && new_thread->IsSuspendThread()) {
716 previous_thread->SetWasRunning(true);
717 }
718 previous_thread->SetContinuousOnSVC(false);
719 previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
720 previous_thread->SetIsRunning(false);
721 if (!previous_thread->IsHLEThread() && !previous_thread->HasExited()) {
722 Core::ARM_Interface& cpu_core = previous_thread->ArmInterface();
723 cpu_core.SaveContext(previous_thread->GetContext32());
724 cpu_core.SaveContext(previous_thread->GetContext64());
725 // Save the TPIDR_EL0 system register in case it was modified.
726 previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0());
727 cpu_core.ClearExclusiveState();
728 }
729 previous_thread->context_guard.unlock();
730 }
731 701
732 std::shared_ptr<Common::Fiber>* old_context; 702 std::shared_ptr<Common::Fiber>* old_context;
733 if (previous_thread != nullptr) { 703 if (previous_thread != nullptr) {
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h
index b6f04dcea..68db4a5ef 100644
--- a/src/core/hle/kernel/scheduler.h
+++ b/src/core/hle/kernel/scheduler.h
@@ -212,8 +212,10 @@ public:
212 212
213 /// The next two are for SingleCore Only. 213 /// The next two are for SingleCore Only.
214 /// Unload current thread before preempting core. 214 /// Unload current thread before preempting core.
215 void Unload(Thread* thread);
215 void Unload(); 216 void Unload();
216 /// Reload current thread after core preemption. 217 /// Reload current thread after core preemption.
218 void Reload(Thread* thread);
217 void Reload(); 219 void Reload();
218 220
219 /// Gets the current running thread 221 /// Gets the current running thread
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index e3b770d66..95d6e2b4d 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2639,6 +2639,9 @@ void Call(Core::System& system, u32 immediate) {
2639 auto& kernel = system.Kernel(); 2639 auto& kernel = system.Kernel();
2640 kernel.EnterSVCProfile(); 2640 kernel.EnterSVCProfile();
2641 2641
2642 auto* thread = system.CurrentScheduler().GetCurrentThread();
2643 thread->SetContinuousOnSVC(true);
2644
2642 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) 2645 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate)
2643 : GetSVCInfo32(immediate); 2646 : GetSVCInfo32(immediate);
2644 if (info) { 2647 if (info) {
@@ -2652,6 +2655,12 @@ void Call(Core::System& system, u32 immediate) {
2652 } 2655 }
2653 2656
2654 kernel.ExitSVCProfile(); 2657 kernel.ExitSVCProfile();
2658
2659 if (!thread->IsContinuousOnSVC()) {
2660 auto* host_context = thread->GetHostContext().get();
2661 host_context->Rewind();
2662 }
2663
2655 system.EnterDynarmicProfile(); 2664 system.EnterDynarmicProfile();
2656} 2665}
2657 2666
diff --git a/src/core/hle/kernel/synchronization_object.h b/src/core/hle/kernel/synchronization_object.h
index f89b24204..7408ed51f 100644
--- a/src/core/hle/kernel/synchronization_object.h
+++ b/src/core/hle/kernel/synchronization_object.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
7#include <memory> 8#include <memory>
8#include <vector> 9#include <vector>
9 10
@@ -56,7 +57,7 @@ public:
56 void ClearWaitingThreads(); 57 void ClearWaitingThreads();
57 58
58protected: 59protected:
59 bool is_signaled{}; // Tells if this sync object is signalled; 60 std::atomic_bool is_signaled{}; // Tells if this sync object is signaled
60 61
61private: 62private:
62 /// Threads waiting for this object to become available 63 /// Threads waiting for this object to become available
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index da0cb26b6..7d1eb2c6e 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -12,7 +12,6 @@
12#include "common/fiber.h" 12#include "common/fiber.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/thread_queue_list.h" 14#include "common/thread_queue_list.h"
15#include "core/arm/arm_interface.h"
16#include "core/core.h" 15#include "core/core.h"
17#include "core/cpu_manager.h" 16#include "core/cpu_manager.h"
18#include "core/hardware_properties.h" 17#include "core/hardware_properties.h"
@@ -62,7 +61,6 @@ void Thread::Stop() {
62 // Mark the TLS slot in the thread's page as free. 61 // Mark the TLS slot in the thread's page as free.
63 owner_process->FreeTLSRegion(tls_address); 62 owner_process->FreeTLSRegion(tls_address);
64 } 63 }
65 arm_interface.reset();
66 has_exited = true; 64 has_exited = true;
67 } 65 }
68 global_handle = 0; 66 global_handle = 0;
@@ -90,10 +88,6 @@ void Thread::ResumeFromWait() {
90 // before actually resuming. We can ignore subsequent wakeups if the thread status has 88 // before actually resuming. We can ignore subsequent wakeups if the thread status has
91 // already been set to ThreadStatus::Ready. 89 // already been set to ThreadStatus::Ready.
92 return; 90 return;
93
94 case ThreadStatus::Running:
95 DEBUG_ASSERT_MSG(false, "Thread with object id {} has already resumed.", GetObjectId());
96 return;
97 case ThreadStatus::Dead: 91 case ThreadStatus::Dead:
98 // This should never happen, as threads must complete before being stopped. 92 // This should never happen, as threads must complete before being stopped.
99 DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.", 93 DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.",
@@ -217,22 +211,9 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
217 thread->tls_address = 0; 211 thread->tls_address = 0;
218 } 212 }
219 213
220 thread->arm_interface.reset(); 214 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
215 // to initialize the context
221 if ((type_flags & THREADTYPE_HLE) == 0) { 216 if ((type_flags & THREADTYPE_HLE) == 0) {
222#ifdef ARCHITECTURE_x86_64
223 if (owner_process && !owner_process->Is64BitProcess()) {
224 thread->arm_interface = std::make_unique<Core::ARM_Dynarmic_32>(
225 system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(),
226 processor_id);
227 } else {
228 thread->arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
229 system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(),
230 processor_id);
231 }
232#else
233#error Platform not supported yet.
234#endif
235
236 ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top), 217 ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top),
237 static_cast<u32>(entry_point), static_cast<u32>(arg)); 218 static_cast<u32>(entry_point), static_cast<u32>(arg));
238 ResetThreadContext64(thread->context_64, stack_top, entry_point, arg); 219 ResetThreadContext64(thread->context_64, stack_top, entry_point, arg);
@@ -268,14 +249,6 @@ VAddr Thread::GetCommandBufferAddress() const {
268 return GetTLSAddress() + command_header_offset; 249 return GetTLSAddress() + command_header_offset;
269} 250}
270 251
271Core::ARM_Interface& Thread::ArmInterface() {
272 return *arm_interface;
273}
274
275const Core::ARM_Interface& Thread::ArmInterface() const {
276 return *arm_interface;
277}
278
279void Thread::SetStatus(ThreadStatus new_status) { 252void Thread::SetStatus(ThreadStatus new_status) {
280 if (new_status == status) { 253 if (new_status == status) {
281 return; 254 return;
@@ -283,7 +256,6 @@ void Thread::SetStatus(ThreadStatus new_status) {
283 256
284 switch (new_status) { 257 switch (new_status) {
285 case ThreadStatus::Ready: 258 case ThreadStatus::Ready:
286 case ThreadStatus::Running:
287 SetSchedulingStatus(ThreadSchedStatus::Runnable); 259 SetSchedulingStatus(ThreadSchedStatus::Runnable);
288 break; 260 break;
289 case ThreadStatus::Dormant: 261 case ThreadStatus::Dormant:
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 8daf79fac..a75071e9b 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -72,7 +72,6 @@ enum ThreadProcessorId : s32 {
72}; 72};
73 73
74enum class ThreadStatus { 74enum class ThreadStatus {
75 Running, ///< Currently running
76 Ready, ///< Ready to run 75 Ready, ///< Ready to run
77 Paused, ///< Paused by SetThreadActivity or debug 76 Paused, ///< Paused by SetThreadActivity or debug
78 WaitHLEEvent, ///< Waiting for hle event to finish 77 WaitHLEEvent, ///< Waiting for hle event to finish
@@ -248,10 +247,6 @@ public:
248 247
249 void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); 248 void SetSynchronizationResults(SynchronizationObject* object, ResultCode result);
250 249
251 Core::ARM_Interface& ArmInterface();
252
253 const Core::ARM_Interface& ArmInterface() const;
254
255 SynchronizationObject* GetSignalingObject() const { 250 SynchronizationObject* GetSignalingObject() const {
256 return signaling_object; 251 return signaling_object;
257 } 252 }
@@ -586,7 +581,6 @@ private:
586 Common::SpinLock context_guard{}; 581 Common::SpinLock context_guard{};
587 ThreadContext32 context_32{}; 582 ThreadContext32 context_32{};
588 ThreadContext64 context_64{}; 583 ThreadContext64 context_64{};
589 std::unique_ptr<Core::ARM_Interface> arm_interface{};
590 std::shared_ptr<Common::Fiber> host_context{}; 584 std::shared_ptr<Common::Fiber> host_context{};
591 585
592 u64 thread_id = 0; 586 u64 thread_id = 0;
diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp
index 95f2446c9..caf329bfb 100644
--- a/src/core/hle/kernel/time_manager.cpp
+++ b/src/core/hle/kernel/time_manager.cpp
@@ -24,11 +24,15 @@ TimeManager::TimeManager(Core::System& system_) : system{system_} {
24 return; 24 return;
25 } 25 }
26 auto thread = this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle); 26 auto thread = this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
27 thread->OnWakeUp(); 27 if (thread) {
28 // Thread can be null if process has exited
29 thread->OnWakeUp();
30 }
28 }); 31 });
29} 32}
30 33
31void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds) { 34void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds) {
35 std::lock_guard lock{mutex};
32 event_handle = timetask->GetGlobalHandle(); 36 event_handle = timetask->GetGlobalHandle();
33 if (nanoseconds > 0) { 37 if (nanoseconds > 0) {
34 ASSERT(timetask); 38 ASSERT(timetask);
@@ -43,6 +47,7 @@ void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64
43} 47}
44 48
45void TimeManager::UnscheduleTimeEvent(Handle event_handle) { 49void TimeManager::UnscheduleTimeEvent(Handle event_handle) {
50 std::lock_guard lock{mutex};
46 if (event_handle == InvalidHandle) { 51 if (event_handle == InvalidHandle) {
47 return; 52 return;
48 } 53 }
@@ -51,7 +56,7 @@ void TimeManager::UnscheduleTimeEvent(Handle event_handle) {
51} 56}
52 57
53void TimeManager::CancelTimeEvent(Thread* time_task) { 58void TimeManager::CancelTimeEvent(Thread* time_task) {
54 Handle event_handle = time_task->GetGlobalHandle(); 59 const Handle event_handle = time_task->GetGlobalHandle();
55 UnscheduleTimeEvent(event_handle); 60 UnscheduleTimeEvent(event_handle);
56} 61}
57 62
diff --git a/src/core/hle/kernel/time_manager.h b/src/core/hle/kernel/time_manager.h
index 307a18765..f39df39a0 100644
--- a/src/core/hle/kernel/time_manager.h
+++ b/src/core/hle/kernel/time_manager.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <mutex>
8#include <unordered_map> 9#include <unordered_map>
9 10
10#include "core/hle/kernel/object.h" 11#include "core/hle/kernel/object.h"
@@ -42,6 +43,7 @@ private:
42 Core::System& system; 43 Core::System& system;
43 std::shared_ptr<Core::Timing::EventType> time_manager_event_type; 44 std::shared_ptr<Core::Timing::EventType> time_manager_event_type;
44 std::unordered_map<Handle, bool> cancelled_events; 45 std::unordered_map<Handle, bool> cancelled_events;
46 std::mutex mutex;
45}; 47};
46 48
47} // namespace Kernel 49} // namespace Kernel
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index fff68326b..9da786b4e 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -527,9 +527,6 @@ public:
527 header.segment_headers[RO_INDEX].memory_size, 527 header.segment_headers[RO_INDEX].memory_size,
528 header.segment_headers[DATA_INDEX].memory_size, nro_address}); 528 header.segment_headers[DATA_INDEX].memory_size, nro_address});
529 529
530 // Invalidate JIT caches for the newly mapped process code
531 system.InvalidateCpuInstructionCaches();
532
533 IPC::ResponseBuilder rb{ctx, 4}; 530 IPC::ResponseBuilder rb{ctx, 4};
534 rb.Push(RESULT_SUCCESS); 531 rb.Push(RESULT_SUCCESS);
535 rb.Push(*map_result); 532 rb.Push(*map_result);
@@ -590,8 +587,6 @@ public:
590 587
591 const auto result{UnmapNro(iter->second)}; 588 const auto result{UnmapNro(iter->second)};
592 589
593 system.InvalidateCpuInstructionCaches();
594
595 nro.erase(iter); 590 nro.erase(iter);
596 591
597 IPC::ResponseBuilder rb{ctx, 2}; 592 IPC::ResponseBuilder rb{ctx, 2};
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp
index d0ee64ad7..10786a541 100644
--- a/src/input_common/mouse/mouse_input.cpp
+++ b/src/input_common/mouse/mouse_input.cpp
@@ -2,9 +2,6 @@
2// Licensed under GPLv2+ 2// Licensed under GPLv2+
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h"
6#include "common/math_util.h"
7#include "common/param_package.h"
8#include "input_common/mouse/mouse_input.h" 5#include "input_common/mouse/mouse_input.h"
9 6
10namespace MouseInput { 7namespace MouseInput {
@@ -24,8 +21,11 @@ void Mouse::UpdateThread() {
24 constexpr int update_time = 10; 21 constexpr int update_time = 10;
25 while (update_thread_running) { 22 while (update_thread_running) {
26 for (MouseInfo& info : mouse_info) { 23 for (MouseInfo& info : mouse_info) {
27 Common::Vec3f angular_direction = {-info.tilt_direction.y, 0.0f, 24 const Common::Vec3f angular_direction{
28 -info.tilt_direction.x}; 25 -info.tilt_direction.y,
26 0.0f,
27 -info.tilt_direction.x,
28 };
29 29
30 info.motion.SetGyroscope(angular_direction * info.tilt_speed); 30 info.motion.SetGyroscope(angular_direction * info.tilt_speed);
31 info.motion.UpdateRotation(update_time * 1000); 31 info.motion.UpdateRotation(update_time * 1000);
@@ -41,22 +41,24 @@ void Mouse::UpdateThread() {
41} 41}
42 42
43void Mouse::UpdateYuzuSettings() { 43void Mouse::UpdateYuzuSettings() {
44 MouseStatus pad_status{}; 44 if (buttons == 0) {
45 if (buttons != 0) { 45 return;
46 pad_status.button = last_button;
47 mouse_queue.Push(pad_status);
48 } 46 }
47
48 mouse_queue.Push(MouseStatus{
49 .button = last_button,
50 });
49} 51}
50 52
51void Mouse::PressButton(int x, int y, int button_) { 53void Mouse::PressButton(int x, int y, int button_) {
52 if (button_ >= static_cast<int>(mouse_info.size())) { 54 const auto button_index = static_cast<std::size_t>(button_);
55 if (button_index >= mouse_info.size()) {
53 return; 56 return;
54 } 57 }
55 58
56 int button = 1 << button_; 59 const auto button = 1U << button_index;
57 const auto button_index = static_cast<std::size_t>(button_);
58 buttons |= static_cast<u16>(button); 60 buttons |= static_cast<u16>(button);
59 last_button = static_cast<MouseButton>(button_); 61 last_button = static_cast<MouseButton>(button_index);
60 62
61 mouse_info[button_index].mouse_origin = Common::MakeVec(x, y); 63 mouse_info[button_index].mouse_origin = Common::MakeVec(x, y);
62 mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y); 64 mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y);
@@ -66,8 +68,8 @@ void Mouse::PressButton(int x, int y, int button_) {
66void Mouse::MouseMove(int x, int y) { 68void Mouse::MouseMove(int x, int y) {
67 for (MouseInfo& info : mouse_info) { 69 for (MouseInfo& info : mouse_info) {
68 if (info.data.pressed) { 70 if (info.data.pressed) {
69 auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin; 71 const auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin;
70 auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position; 72 const auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position;
71 info.last_mouse_position = Common::MakeVec(x, y); 73 info.last_mouse_position = Common::MakeVec(x, y);
72 info.data.axis = {mouse_move.x, -mouse_move.y}; 74 info.data.axis = {mouse_move.x, -mouse_move.y};
73 75
@@ -82,12 +84,12 @@ void Mouse::MouseMove(int x, int y) {
82} 84}
83 85
84void Mouse::ReleaseButton(int button_) { 86void Mouse::ReleaseButton(int button_) {
85 if (button_ >= static_cast<int>(mouse_info.size())) { 87 const auto button_index = static_cast<std::size_t>(button_);
88 if (button_index >= mouse_info.size()) {
86 return; 89 return;
87 } 90 }
88 91
89 int button = 1 << button_; 92 const auto button = 1U << button_index;
90 const auto button_index = static_cast<std::size_t>(button_);
91 buttons &= static_cast<u16>(0xFF - button); 93 buttons &= static_cast<u16>(0xFF - button);
92 94
93 mouse_info[button_index].tilt_speed = 0; 95 mouse_info[button_index].tilt_speed = 0;
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h
index 761663334..65e64bee7 100644
--- a/src/input_common/mouse/mouse_input.h
+++ b/src/input_common/mouse/mouse_input.h
@@ -4,15 +4,14 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <algorithm> 7#include <array>
8#include <functional>
9#include <mutex> 8#include <mutex>
10#include <thread> 9#include <thread>
11#include <unordered_map> 10
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "common/threadsafe_queue.h" 12#include "common/threadsafe_queue.h"
13#include "common/vector_math.h"
14#include "core/frontend/input.h" 14#include "core/frontend/input.h"
15#include "input_common/main.h"
16#include "input_common/motion_input.h" 15#include "input_common/motion_input.h"
17 16
18namespace MouseInput { 17namespace MouseInput {
@@ -50,7 +49,7 @@ public:
50 * Signals that a button is pressed. 49 * Signals that a button is pressed.
51 * @param x the x-coordinate of the cursor 50 * @param x the x-coordinate of the cursor
52 * @param y the y-coordinate of the cursor 51 * @param y the y-coordinate of the cursor
53 * @param button the button pressed 52 * @param button_ the button pressed
54 */ 53 */
55 void PressButton(int x, int y, int button_); 54 void PressButton(int x, int y, int button_);
56 55
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp
index 6213f3dbd..7445ad3ad 100644
--- a/src/input_common/mouse/mouse_poller.cpp
+++ b/src/input_common/mouse/mouse_poller.cpp
@@ -2,11 +2,9 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <atomic>
6#include <list>
7#include <mutex> 5#include <mutex>
8#include <utility> 6#include <utility>
9#include "common/assert.h" 7
10#include "common/threadsafe_queue.h" 8#include "common/threadsafe_queue.h"
11#include "input_common/mouse/mouse_input.h" 9#include "input_common/mouse/mouse_input.h"
12#include "input_common/mouse/mouse_poller.h" 10#include "input_common/mouse/mouse_poller.h"
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp
index b1d675cdb..7d8d6ee3c 100644
--- a/src/video_core/command_classes/codecs/vp9.cpp
+++ b/src/video_core/command_classes/codecs/vp9.cpp
@@ -355,7 +355,7 @@ void VP9::WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_
355Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) { 355Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) {
356 PictureInfo picture_info{}; 356 PictureInfo picture_info{};
357 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo)); 357 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo));
358 Vp9PictureInfo vp9_info = std::move(picture_info.Convert()); 358 Vp9PictureInfo vp9_info = picture_info.Convert();
359 359
360 InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy); 360 InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy);
361 361
@@ -377,7 +377,7 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
377 Vp9FrameContainer frame{}; 377 Vp9FrameContainer frame{};
378 { 378 {
379 gpu.SyncGuestHost(); 379 gpu.SyncGuestHost();
380 frame.info = std::move(GetVp9PictureInfo(state)); 380 frame.info = GetVp9PictureInfo(state);
381 frame.bit_stream.resize(frame.info.bitstream_size); 381 frame.bit_stream.resize(frame.info.bitstream_size);
382 gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(), 382 gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(),
383 frame.info.bitstream_size); 383 frame.info.bitstream_size);
@@ -385,29 +385,29 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
385 // Buffer two frames, saving the last show frame info 385 // Buffer two frames, saving the last show frame info
386 if (!next_next_frame.bit_stream.empty()) { 386 if (!next_next_frame.bit_stream.empty()) {
387 Vp9FrameContainer temp{ 387 Vp9FrameContainer temp{
388 .info = std::move(frame.info), 388 .info = frame.info,
389 .bit_stream = std::move(frame.bit_stream), 389 .bit_stream = std::move(frame.bit_stream),
390 }; 390 };
391 next_next_frame.info.show_frame = frame.info.last_frame_shown; 391 next_next_frame.info.show_frame = frame.info.last_frame_shown;
392 frame.info = std::move(next_next_frame.info); 392 frame.info = next_next_frame.info;
393 frame.bit_stream = std::move(next_next_frame.bit_stream); 393 frame.bit_stream = std::move(next_next_frame.bit_stream);
394 next_next_frame = std::move(temp); 394 next_next_frame = std::move(temp);
395 395
396 if (!next_frame.bit_stream.empty()) { 396 if (!next_frame.bit_stream.empty()) {
397 Vp9FrameContainer temp2{ 397 Vp9FrameContainer temp2{
398 .info = std::move(frame.info), 398 .info = frame.info,
399 .bit_stream = std::move(frame.bit_stream), 399 .bit_stream = std::move(frame.bit_stream),
400 }; 400 };
401 next_frame.info.show_frame = frame.info.last_frame_shown; 401 next_frame.info.show_frame = frame.info.last_frame_shown;
402 frame.info = std::move(next_frame.info); 402 frame.info = next_frame.info;
403 frame.bit_stream = std::move(next_frame.bit_stream); 403 frame.bit_stream = std::move(next_frame.bit_stream);
404 next_frame = std::move(temp2); 404 next_frame = std::move(temp2);
405 } else { 405 } else {
406 next_frame.info = std::move(frame.info); 406 next_frame.info = frame.info;
407 next_frame.bit_stream = std::move(frame.bit_stream); 407 next_frame.bit_stream = std::move(frame.bit_stream);
408 } 408 }
409 } else { 409 } else {
410 next_next_frame.info = std::move(frame.info); 410 next_next_frame.info = frame.info;
411 next_next_frame.bit_stream = std::move(frame.bit_stream); 411 next_next_frame.bit_stream = std::move(frame.bit_stream);
412 } 412 }
413 return frame; 413 return frame;
@@ -806,8 +806,8 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
806const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state) { 806const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state) {
807 std::vector<u8> bitstream; 807 std::vector<u8> bitstream;
808 { 808 {
809 Vp9FrameContainer curr_frame = std::move(GetCurrentFrame(state)); 809 Vp9FrameContainer curr_frame = GetCurrentFrame(state);
810 current_frame_info = std::move(curr_frame.info); 810 current_frame_info = curr_frame.info;
811 bitstream = std::move(curr_frame.bit_stream); 811 bitstream = std::move(curr_frame.bit_stream);
812 } 812 }
813 813
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp
index 248443027..6cfc193fa 100644
--- a/src/video_core/command_classes/vic.cpp
+++ b/src/video_core/command_classes/vic.cpp
@@ -58,7 +58,7 @@ void Vic::Execute() {
58 return; 58 return;
59 } 59 }
60 const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)}; 60 const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)};
61 const AVFramePtr frame_ptr = std::move(nvdec_processor->GetFrame()); 61 const AVFramePtr frame_ptr = nvdec_processor->GetFrame();
62 const auto* frame = frame_ptr.get(); 62 const auto* frame = frame_ptr.get();
63 if (!frame || frame->width == 0 || frame->height == 0) { 63 if (!frame || frame->width == 0 || frame->height == 0) {
64 return; 64 return;
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 3439cb333..a20824719 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -25,7 +25,6 @@ namespace {
25 25
26constexpr std::array<std::array<Qt::GlobalColor, 2>, 10> WaitTreeColors{{ 26constexpr std::array<std::array<Qt::GlobalColor, 2>, 10> WaitTreeColors{{
27 {Qt::GlobalColor::darkGreen, Qt::GlobalColor::green}, 27 {Qt::GlobalColor::darkGreen, Qt::GlobalColor::green},
28 {Qt::GlobalColor::darkGreen, Qt::GlobalColor::green},
29 {Qt::GlobalColor::darkBlue, Qt::GlobalColor::cyan}, 28 {Qt::GlobalColor::darkBlue, Qt::GlobalColor::cyan},
30 {Qt::GlobalColor::lightGray, Qt::GlobalColor::lightGray}, 29 {Qt::GlobalColor::lightGray, Qt::GlobalColor::lightGray},
31 {Qt::GlobalColor::lightGray, Qt::GlobalColor::lightGray}, 30 {Qt::GlobalColor::lightGray, Qt::GlobalColor::lightGray},
@@ -239,9 +238,6 @@ QString WaitTreeThread::GetText() const {
239 const auto& thread = static_cast<const Kernel::Thread&>(object); 238 const auto& thread = static_cast<const Kernel::Thread&>(object);
240 QString status; 239 QString status;
241 switch (thread.GetStatus()) { 240 switch (thread.GetStatus()) {
242 case Kernel::ThreadStatus::Running:
243 status = tr("running");
244 break;
245 case Kernel::ThreadStatus::Ready: 241 case Kernel::ThreadStatus::Ready:
246 if (!thread.IsPaused()) { 242 if (!thread.IsPaused()) {
247 if (thread.WasRunning()) { 243 if (thread.WasRunning()) {
@@ -298,34 +294,32 @@ QColor WaitTreeThread::GetColor() const {
298 294
299 const auto& thread = static_cast<const Kernel::Thread&>(object); 295 const auto& thread = static_cast<const Kernel::Thread&>(object);
300 switch (thread.GetStatus()) { 296 switch (thread.GetStatus()) {
301 case Kernel::ThreadStatus::Running:
302 return QColor(WaitTreeColors[0][color_index]);
303 case Kernel::ThreadStatus::Ready: 297 case Kernel::ThreadStatus::Ready:
304 if (!thread.IsPaused()) { 298 if (!thread.IsPaused()) {
305 if (thread.WasRunning()) { 299 if (thread.WasRunning()) {
306 return QColor(WaitTreeColors[1][color_index]); 300 return QColor(WaitTreeColors[0][color_index]);
307 } else { 301 } else {
308 return QColor(WaitTreeColors[2][color_index]); 302 return QColor(WaitTreeColors[1][color_index]);
309 } 303 }
310 } else { 304 } else {
311 return QColor(WaitTreeColors[3][color_index]); 305 return QColor(WaitTreeColors[2][color_index]);
312 } 306 }
313 case Kernel::ThreadStatus::Paused: 307 case Kernel::ThreadStatus::Paused:
314 return QColor(WaitTreeColors[4][color_index]); 308 return QColor(WaitTreeColors[3][color_index]);
315 case Kernel::ThreadStatus::WaitHLEEvent: 309 case Kernel::ThreadStatus::WaitHLEEvent:
316 case Kernel::ThreadStatus::WaitIPC: 310 case Kernel::ThreadStatus::WaitIPC:
317 return QColor(WaitTreeColors[5][color_index]); 311 return QColor(WaitTreeColors[4][color_index]);
318 case Kernel::ThreadStatus::WaitSleep: 312 case Kernel::ThreadStatus::WaitSleep:
319 return QColor(WaitTreeColors[6][color_index]); 313 return QColor(WaitTreeColors[5][color_index]);
320 case Kernel::ThreadStatus::WaitSynch: 314 case Kernel::ThreadStatus::WaitSynch:
321 case Kernel::ThreadStatus::WaitMutex: 315 case Kernel::ThreadStatus::WaitMutex:
322 case Kernel::ThreadStatus::WaitCondVar: 316 case Kernel::ThreadStatus::WaitCondVar:
323 case Kernel::ThreadStatus::WaitArb: 317 case Kernel::ThreadStatus::WaitArb:
324 return QColor(WaitTreeColors[7][color_index]); 318 return QColor(WaitTreeColors[6][color_index]);
325 case Kernel::ThreadStatus::Dormant: 319 case Kernel::ThreadStatus::Dormant:
326 return QColor(WaitTreeColors[8][color_index]); 320 return QColor(WaitTreeColors[7][color_index]);
327 case Kernel::ThreadStatus::Dead: 321 case Kernel::ThreadStatus::Dead:
328 return QColor(WaitTreeColors[9][color_index]); 322 return QColor(WaitTreeColors[8][color_index]);
329 default: 323 default:
330 return WaitTreeItem::GetColor(); 324 return WaitTreeItem::GetColor();
331 } 325 }