summaryrefslogtreecommitdiff
path: root/src/core/core_cpu.cpp
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-01-25 18:55:32 -0400
committerGravatar Fernando Sahmkow2020-01-25 18:55:32 -0400
commit4d6a86b03fe6ae0d98838a21613b66d5196150af (patch)
tree21f4b8e63e6435b2d816936af8b494882a3cdfb2 /src/core/core_cpu.cpp
parentKernel: Implement Physical Core. (diff)
downloadyuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.gz
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.xz
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.zip
Core: Refactor CPU Management.
This commit moves ARM Interface and Scheduler handling into the kernel.
Diffstat (limited to 'src/core/core_cpu.cpp')
-rw-r--r--src/core/core_cpu.cpp76
1 files changed, 10 insertions, 66 deletions
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 630cd4feb..bcfdf0198 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -14,6 +14,8 @@
14#include "core/core.h" 14#include "core/core.h"
15#include "core/core_cpu.h" 15#include "core/core_cpu.h"
16#include "core/core_timing.h" 16#include "core/core_timing.h"
17#include "core/hle/kernel/kernel.h"
18#include "core/hle/kernel/physical_core.h"
17#include "core/hle/kernel/scheduler.h" 19#include "core/hle/kernel/scheduler.h"
18#include "core/hle/kernel/thread.h" 20#include "core/hle/kernel/thread.h"
19#include "core/hle/lock.h" 21#include "core/hle/lock.h"
@@ -21,68 +23,15 @@
21 23
22namespace Core { 24namespace Core {
23 25
24void CpuBarrier::NotifyEnd() { 26Cpu::Cpu(System& system, std::size_t core_index)
25 std::unique_lock lock{mutex}; 27 : global_scheduler{system.GlobalScheduler()},
26 end = true; 28 physical_core{system.Kernel().PhysicalCore(core_index)}, core_timing{system.CoreTiming()},
27 condition.notify_all(); 29 core_index{core_index} {
28}
29
30bool CpuBarrier::Rendezvous() {
31 if (!Settings::values.use_multi_core) {
32 // Meaningless when running in single-core mode
33 return true;
34 }
35
36 if (!end) {
37 std::unique_lock lock{mutex};
38
39 --cores_waiting;
40 if (!cores_waiting) {
41 cores_waiting = NUM_CPU_CORES;
42 condition.notify_all();
43 return true;
44 }
45
46 condition.wait(lock);
47 return true;
48 }
49
50 return false;
51}
52
53Cpu::Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_barrier,
54 std::size_t core_index)
55 : cpu_barrier{cpu_barrier}, global_scheduler{system.GlobalScheduler()},
56 core_timing{system.CoreTiming()}, core_index{core_index} {
57#ifdef ARCHITECTURE_x86_64
58 arm_interface = std::make_unique<ARM_Dynarmic>(system, exclusive_monitor, core_index);
59#else
60 arm_interface = std::make_unique<ARM_Unicorn>(system);
61 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
62#endif
63
64 scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface, core_index);
65} 30}
66 31
67Cpu::~Cpu() = default; 32Cpu::~Cpu() = default;
68 33
69std::unique_ptr<ExclusiveMonitor> Cpu::MakeExclusiveMonitor(
70 [[maybe_unused]] Memory::Memory& memory, [[maybe_unused]] std::size_t num_cores) {
71#ifdef ARCHITECTURE_x86_64
72 return std::make_unique<DynarmicExclusiveMonitor>(memory, num_cores);
73#else
74 // TODO(merry): Passthrough exclusive monitor
75 return nullptr;
76#endif
77}
78
79void Cpu::RunLoop(bool tight_loop) { 34void Cpu::RunLoop(bool tight_loop) {
80 // Wait for all other CPU cores to complete the previous slice, such that they run in lock-step
81 if (!cpu_barrier.Rendezvous()) {
82 // If rendezvous failed, session has been killed
83 return;
84 }
85
86 Reschedule(); 35 Reschedule();
87 36
88 // If we don't have a currently active thread then don't execute instructions, 37 // If we don't have a currently active thread then don't execute instructions,
@@ -92,12 +41,10 @@ void Cpu::RunLoop(bool tight_loop) {
92 core_timing.Idle(); 41 core_timing.Idle();
93 } else { 42 } else {
94 if (tight_loop) { 43 if (tight_loop) {
95 arm_interface->Run(); 44 physical_core.Run();
96 } else { 45 } else {
97 arm_interface->Step(); 46 physical_core.Step();
98 } 47 }
99 // We are stopping a run, exclusive state must be cleared
100 arm_interface->ClearExclusiveState();
101 } 48 }
102 core_timing.Advance(); 49 core_timing.Advance();
103 50
@@ -109,7 +56,7 @@ void Cpu::SingleStep() {
109} 56}
110 57
111void Cpu::PrepareReschedule() { 58void Cpu::PrepareReschedule() {
112 arm_interface->PrepareReschedule(); 59 physical_core.Stop();
113} 60}
114 61
115void Cpu::Reschedule() { 62void Cpu::Reschedule() {
@@ -117,11 +64,8 @@ void Cpu::Reschedule() {
117 std::lock_guard lock(HLE::g_hle_lock); 64 std::lock_guard lock(HLE::g_hle_lock);
118 65
119 global_scheduler.SelectThread(core_index); 66 global_scheduler.SelectThread(core_index);
120 scheduler->TryDoContextSwitch();
121}
122 67
123void Cpu::Shutdown() { 68 physical_core.Scheduler().TryDoContextSwitch();
124 scheduler->Shutdown();
125} 69}
126 70
127} // namespace Core 71} // namespace Core