diff options
| author | 2018-07-22 12:48:44 -0400 | |
|---|---|---|
| committer | 2018-07-22 12:48:44 -0400 | |
| commit | 5fc99553d20d7d747730f7da4d12bdeb0593adb2 (patch) | |
| tree | 4f3217d3f564c47b8aeecac046e389ba6d3d07ed | |
| parent | Merge pull request #772 from MerryMage/dynarmic (diff) | |
| parent | Implement exclusive monitor (diff) | |
| download | yuzu-5fc99553d20d7d747730f7da4d12bdeb0593adb2.tar.gz yuzu-5fc99553d20d7d747730f7da4d12bdeb0593adb2.tar.xz yuzu-5fc99553d20d7d747730f7da4d12bdeb0593adb2.zip | |
Merge pull request #638 from MerryMage/mp
Implement exclusive monitor
Diffstat (limited to '')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 67 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 30 | ||||
| -rw-r--r-- | src/core/arm/exclusive_monitor.cpp | 7 | ||||
| -rw-r--r-- | src/core/arm/exclusive_monitor.h | 23 | ||||
| -rw-r--r-- | src/core/core.cpp | 3 | ||||
| -rw-r--r-- | src/core/core.h | 12 | ||||
| -rw-r--r-- | src/core/core_cpu.cpp | 19 | ||||
| -rw-r--r-- | src/core/core_cpu.h | 10 |
9 files changed, 160 insertions, 13 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 0a5d58eea..27a5de7fd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | add_library(core STATIC | 1 | add_library(core STATIC |
| 2 | arm/arm_interface.h | 2 | arm/arm_interface.h |
| 3 | arm/exclusive_monitor.cpp | ||
| 4 | arm/exclusive_monitor.h | ||
| 3 | arm/unicorn/arm_unicorn.cpp | 5 | arm/unicorn/arm_unicorn.cpp |
| 4 | arm/unicorn/arm_unicorn.h | 6 | arm/unicorn/arm_unicorn.h |
| 5 | core.cpp | 7 | core.cpp |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 5d7efc9b6..83c09db2b 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -102,18 +102,28 @@ public: | |||
| 102 | u64 tpidr_el0 = 0; | 102 | u64 tpidr_el0 = 0; |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_Callbacks>& cb) { | 105 | std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() { |
| 106 | const auto page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data(); | 106 | const auto page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data(); |
| 107 | 107 | ||
| 108 | Dynarmic::A64::UserConfig config; | 108 | Dynarmic::A64::UserConfig config; |
| 109 | |||
| 110 | // Callbacks | ||
| 109 | config.callbacks = cb.get(); | 111 | config.callbacks = cb.get(); |
| 112 | |||
| 113 | // Memory | ||
| 114 | config.page_table = reinterpret_cast<void**>(page_table); | ||
| 115 | config.page_table_address_space_bits = Memory::ADDRESS_SPACE_BITS; | ||
| 116 | config.silently_mirror_page_table = false; | ||
| 117 | |||
| 118 | // Multi-process state | ||
| 119 | config.processor_id = core_index; | ||
| 120 | config.global_monitor = &exclusive_monitor->monitor; | ||
| 121 | |||
| 122 | // System registers | ||
| 110 | config.tpidrro_el0 = &cb->tpidrro_el0; | 123 | config.tpidrro_el0 = &cb->tpidrro_el0; |
| 111 | config.tpidr_el0 = &cb->tpidr_el0; | 124 | config.tpidr_el0 = &cb->tpidr_el0; |
| 112 | config.dczid_el0 = 4; | 125 | config.dczid_el0 = 4; |
| 113 | config.ctr_el0 = 0x8444c004; | 126 | config.ctr_el0 = 0x8444c004; |
| 114 | config.page_table = reinterpret_cast<void**>(page_table); | ||
| 115 | config.page_table_address_space_bits = Memory::ADDRESS_SPACE_BITS; | ||
| 116 | config.silently_mirror_page_table = false; | ||
| 117 | 127 | ||
| 118 | return std::make_unique<Dynarmic::A64::Jit>(config); | 128 | return std::make_unique<Dynarmic::A64::Jit>(config); |
| 119 | } | 129 | } |
| @@ -128,8 +138,11 @@ void ARM_Dynarmic::Step() { | |||
| 128 | cb->InterpreterFallback(jit->GetPC(), 1); | 138 | cb->InterpreterFallback(jit->GetPC(), 1); |
| 129 | } | 139 | } |
| 130 | 140 | ||
| 131 | ARM_Dynarmic::ARM_Dynarmic() | 141 | ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index) |
| 132 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), jit(MakeJit(cb)) { | 142 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), |
| 143 | jit(MakeJit()), exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>( | ||
| 144 | exclusive_monitor)}, | ||
| 145 | core_index{core_index} { | ||
| 133 | ARM_Interface::ThreadContext ctx; | 146 | ARM_Interface::ThreadContext ctx; |
| 134 | inner_unicorn.SaveContext(ctx); | 147 | inner_unicorn.SaveContext(ctx); |
| 135 | LoadContext(ctx); | 148 | LoadContext(ctx); |
| @@ -237,6 +250,46 @@ void ARM_Dynarmic::ClearExclusiveState() { | |||
| 237 | } | 250 | } |
| 238 | 251 | ||
| 239 | void ARM_Dynarmic::PageTableChanged() { | 252 | void ARM_Dynarmic::PageTableChanged() { |
| 240 | jit = MakeJit(cb); | 253 | jit = MakeJit(); |
| 241 | current_page_table = Memory::GetCurrentPageTable(); | 254 | current_page_table = Memory::GetCurrentPageTable(); |
| 242 | } | 255 | } |
| 256 | |||
| 257 | DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(size_t core_count) : monitor(core_count) {} | ||
| 258 | DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; | ||
| 259 | |||
| 260 | void DynarmicExclusiveMonitor::SetExclusive(size_t core_index, u64 addr) { | ||
| 261 | // Size doesn't actually matter. | ||
| 262 | monitor.Mark(core_index, addr, 16); | ||
| 263 | } | ||
| 264 | |||
| 265 | void DynarmicExclusiveMonitor::ClearExclusive() { | ||
| 266 | monitor.Clear(); | ||
| 267 | } | ||
| 268 | |||
| 269 | bool DynarmicExclusiveMonitor::ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) { | ||
| 270 | return monitor.DoExclusiveOperation(core_index, vaddr, 1, | ||
| 271 | [&] { Memory::Write8(vaddr, value); }); | ||
| 272 | } | ||
| 273 | |||
| 274 | bool DynarmicExclusiveMonitor::ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) { | ||
| 275 | return monitor.DoExclusiveOperation(core_index, vaddr, 2, | ||
| 276 | [&] { Memory::Write16(vaddr, value); }); | ||
| 277 | } | ||
| 278 | |||
| 279 | bool DynarmicExclusiveMonitor::ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) { | ||
| 280 | return monitor.DoExclusiveOperation(core_index, vaddr, 4, | ||
| 281 | [&] { Memory::Write32(vaddr, value); }); | ||
| 282 | } | ||
| 283 | |||
| 284 | bool DynarmicExclusiveMonitor::ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) { | ||
| 285 | return monitor.DoExclusiveOperation(core_index, vaddr, 8, | ||
| 286 | [&] { Memory::Write64(vaddr, value); }); | ||
| 287 | } | ||
| 288 | |||
| 289 | bool DynarmicExclusiveMonitor::ExclusiveWrite128(size_t core_index, u64 vaddr, | ||
| 290 | std::array<std::uint64_t, 2> value) { | ||
| 291 | return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] { | ||
| 292 | Memory::Write64(vaddr, value[0]); | ||
| 293 | Memory::Write64(vaddr, value[1]); | ||
| 294 | }); | ||
| 295 | } | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index a9891ac4f..0fa8b417c 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -6,15 +6,18 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <dynarmic/A64/a64.h> | 8 | #include <dynarmic/A64/a64.h> |
| 9 | #include <dynarmic/A64/exclusive_monitor.h> | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "core/arm/arm_interface.h" | 11 | #include "core/arm/arm_interface.h" |
| 12 | #include "core/arm/exclusive_monitor.h" | ||
| 11 | #include "core/arm/unicorn/arm_unicorn.h" | 13 | #include "core/arm/unicorn/arm_unicorn.h" |
| 12 | 14 | ||
| 13 | class ARM_Dynarmic_Callbacks; | 15 | class ARM_Dynarmic_Callbacks; |
| 16 | class DynarmicExclusiveMonitor; | ||
| 14 | 17 | ||
| 15 | class ARM_Dynarmic final : public ARM_Interface { | 18 | class ARM_Dynarmic final : public ARM_Interface { |
| 16 | public: | 19 | public: |
| 17 | ARM_Dynarmic(); | 20 | ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index); |
| 18 | ~ARM_Dynarmic(); | 21 | ~ARM_Dynarmic(); |
| 19 | 22 | ||
| 20 | void MapBackingMemory(VAddr address, size_t size, u8* memory, | 23 | void MapBackingMemory(VAddr address, size_t size, u8* memory, |
| @@ -47,10 +50,35 @@ public: | |||
| 47 | void PageTableChanged() override; | 50 | void PageTableChanged() override; |
| 48 | 51 | ||
| 49 | private: | 52 | private: |
| 53 | std::unique_ptr<Dynarmic::A64::Jit> MakeJit(); | ||
| 54 | |||
| 50 | friend class ARM_Dynarmic_Callbacks; | 55 | friend class ARM_Dynarmic_Callbacks; |
| 51 | std::unique_ptr<ARM_Dynarmic_Callbacks> cb; | 56 | std::unique_ptr<ARM_Dynarmic_Callbacks> cb; |
| 52 | std::unique_ptr<Dynarmic::A64::Jit> jit; | 57 | std::unique_ptr<Dynarmic::A64::Jit> jit; |
| 53 | ARM_Unicorn inner_unicorn; | 58 | ARM_Unicorn inner_unicorn; |
| 54 | 59 | ||
| 60 | size_t core_index; | ||
| 61 | std::shared_ptr<DynarmicExclusiveMonitor> exclusive_monitor; | ||
| 62 | |||
| 55 | Memory::PageTable* current_page_table = nullptr; | 63 | Memory::PageTable* current_page_table = nullptr; |
| 56 | }; | 64 | }; |
| 65 | |||
| 66 | class DynarmicExclusiveMonitor final : public ExclusiveMonitor { | ||
| 67 | public: | ||
| 68 | explicit DynarmicExclusiveMonitor(size_t core_count); | ||
| 69 | ~DynarmicExclusiveMonitor(); | ||
| 70 | |||
| 71 | void SetExclusive(size_t core_index, u64 addr) override; | ||
| 72 | void ClearExclusive() override; | ||
| 73 | |||
| 74 | bool ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) override; | ||
| 75 | bool ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) override; | ||
| 76 | bool ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) override; | ||
| 77 | bool ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) override; | ||
| 78 | bool ExclusiveWrite128(size_t core_index, u64 vaddr, | ||
| 79 | std::array<std::uint64_t, 2> value) override; | ||
| 80 | |||
| 81 | private: | ||
| 82 | friend class ARM_Dynarmic; | ||
| 83 | Dynarmic::A64::ExclusiveMonitor monitor; | ||
| 84 | }; | ||
diff --git a/src/core/arm/exclusive_monitor.cpp b/src/core/arm/exclusive_monitor.cpp new file mode 100644 index 000000000..cb8c81d80 --- /dev/null +++ b/src/core/arm/exclusive_monitor.cpp | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/arm/exclusive_monitor.h" | ||
| 6 | |||
| 7 | ExclusiveMonitor::~ExclusiveMonitor() = default; | ||
diff --git a/src/core/arm/exclusive_monitor.h b/src/core/arm/exclusive_monitor.h new file mode 100644 index 000000000..acfcdb94c --- /dev/null +++ b/src/core/arm/exclusive_monitor.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 10 | class ExclusiveMonitor { | ||
| 11 | public: | ||
| 12 | virtual ~ExclusiveMonitor(); | ||
| 13 | |||
| 14 | virtual void SetExclusive(size_t core_index, u64 addr) = 0; | ||
| 15 | virtual void ClearExclusive() = 0; | ||
| 16 | |||
| 17 | virtual bool ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) = 0; | ||
| 18 | virtual bool ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) = 0; | ||
| 19 | virtual bool ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) = 0; | ||
| 20 | virtual bool ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) = 0; | ||
| 21 | virtual bool ExclusiveWrite128(size_t core_index, u64 vaddr, | ||
| 22 | std::array<std::uint64_t, 2> value) = 0; | ||
| 23 | }; | ||
diff --git a/src/core/core.cpp b/src/core/core.cpp index 9bd9f4bd9..b7f4b4532 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -171,8 +171,9 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { | |||
| 171 | current_process = Kernel::Process::Create("main"); | 171 | current_process = Kernel::Process::Create("main"); |
| 172 | 172 | ||
| 173 | cpu_barrier = std::make_shared<CpuBarrier>(); | 173 | cpu_barrier = std::make_shared<CpuBarrier>(); |
| 174 | cpu_exclusive_monitor = Cpu::MakeExclusiveMonitor(cpu_cores.size()); | ||
| 174 | for (size_t index = 0; index < cpu_cores.size(); ++index) { | 175 | for (size_t index = 0; index < cpu_cores.size(); ++index) { |
| 175 | cpu_cores[index] = std::make_shared<Cpu>(cpu_barrier, index); | 176 | cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); |
| 176 | } | 177 | } |
| 177 | 178 | ||
| 178 | gpu_core = std::make_unique<Tegra::GPU>(); | 179 | gpu_core = std::make_unique<Tegra::GPU>(); |
diff --git a/src/core/core.h b/src/core/core.h index c6f69f001..c123fe401 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <thread> | 10 | #include <thread> |
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "core/arm/exclusive_monitor.h" | ||
| 12 | #include "core/core_cpu.h" | 13 | #include "core/core_cpu.h" |
| 13 | #include "core/hle/kernel/kernel.h" | 14 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/scheduler.h" | 15 | #include "core/hle/kernel/scheduler.h" |
| @@ -114,6 +115,11 @@ public: | |||
| 114 | return CurrentCpuCore().ArmInterface(); | 115 | return CurrentCpuCore().ArmInterface(); |
| 115 | } | 116 | } |
| 116 | 117 | ||
| 118 | /// Gets the index of the currently running CPU core | ||
| 119 | size_t CurrentCoreIndex() { | ||
| 120 | return CurrentCpuCore().CoreIndex(); | ||
| 121 | } | ||
| 122 | |||
| 117 | /// Gets an ARM interface to the CPU core with the specified index | 123 | /// Gets an ARM interface to the CPU core with the specified index |
| 118 | ARM_Interface& ArmInterface(size_t core_index); | 124 | ARM_Interface& ArmInterface(size_t core_index); |
| 119 | 125 | ||
| @@ -130,6 +136,11 @@ public: | |||
| 130 | return *CurrentCpuCore().Scheduler(); | 136 | return *CurrentCpuCore().Scheduler(); |
| 131 | } | 137 | } |
| 132 | 138 | ||
| 139 | /// Gets the exclusive monitor | ||
| 140 | ExclusiveMonitor& Monitor() { | ||
| 141 | return *cpu_exclusive_monitor; | ||
| 142 | } | ||
| 143 | |||
| 133 | /// Gets the scheduler for the CPU core with the specified index | 144 | /// Gets the scheduler for the CPU core with the specified index |
| 134 | const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index); | 145 | const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index); |
| 135 | 146 | ||
| @@ -186,6 +197,7 @@ private: | |||
| 186 | std::unique_ptr<Tegra::GPU> gpu_core; | 197 | std::unique_ptr<Tegra::GPU> gpu_core; |
| 187 | std::shared_ptr<Tegra::DebugContext> debug_context; | 198 | std::shared_ptr<Tegra::DebugContext> debug_context; |
| 188 | Kernel::SharedPtr<Kernel::Process> current_process; | 199 | Kernel::SharedPtr<Kernel::Process> current_process; |
| 200 | std::shared_ptr<ExclusiveMonitor> cpu_exclusive_monitor; | ||
| 189 | std::shared_ptr<CpuBarrier> cpu_barrier; | 201 | std::shared_ptr<CpuBarrier> cpu_barrier; |
| 190 | std::array<std::shared_ptr<Cpu>, NUM_CPU_CORES> cpu_cores; | 202 | std::array<std::shared_ptr<Cpu>, NUM_CPU_CORES> cpu_cores; |
| 191 | std::array<std::unique_ptr<std::thread>, NUM_CPU_CORES - 1> cpu_core_threads; | 203 | std::array<std::unique_ptr<std::thread>, NUM_CPU_CORES - 1> cpu_core_threads; |
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp index f22d6a9d0..54e15a701 100644 --- a/src/core/core_cpu.cpp +++ b/src/core/core_cpu.cpp | |||
| @@ -48,14 +48,15 @@ bool CpuBarrier::Rendezvous() { | |||
| 48 | return false; | 48 | return false; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index) | 51 | Cpu::Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, |
| 52 | std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index) | ||
| 52 | : cpu_barrier{std::move(cpu_barrier)}, core_index{core_index} { | 53 | : cpu_barrier{std::move(cpu_barrier)}, core_index{core_index} { |
| 53 | 54 | ||
| 54 | if (Settings::values.use_cpu_jit) { | 55 | if (Settings::values.use_cpu_jit) { |
| 55 | #ifdef ARCHITECTURE_x86_64 | 56 | #ifdef ARCHITECTURE_x86_64 |
| 56 | arm_interface = std::make_shared<ARM_Dynarmic>(); | 57 | arm_interface = std::make_shared<ARM_Dynarmic>(exclusive_monitor, core_index); |
| 57 | #else | 58 | #else |
| 58 | cpu_core = std::make_shared<ARM_Unicorn>(); | 59 | arm_interface = std::make_shared<ARM_Unicorn>(); |
| 59 | LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); | 60 | LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); |
| 60 | #endif | 61 | #endif |
| 61 | } else { | 62 | } else { |
| @@ -65,6 +66,18 @@ Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index) | |||
| 65 | scheduler = std::make_shared<Kernel::Scheduler>(arm_interface.get()); | 66 | scheduler = std::make_shared<Kernel::Scheduler>(arm_interface.get()); |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 69 | std::shared_ptr<ExclusiveMonitor> Cpu::MakeExclusiveMonitor(size_t num_cores) { | ||
| 70 | if (Settings::values.use_cpu_jit) { | ||
| 71 | #ifdef ARCHITECTURE_x86_64 | ||
| 72 | return std::make_shared<DynarmicExclusiveMonitor>(num_cores); | ||
| 73 | #else | ||
| 74 | return nullptr; // TODO(merry): Passthrough exclusive monitor | ||
| 75 | #endif | ||
| 76 | } else { | ||
| 77 | return nullptr; // TODO(merry): Passthrough exclusive monitor | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 68 | void Cpu::RunLoop(bool tight_loop) { | 81 | void Cpu::RunLoop(bool tight_loop) { |
| 69 | // Wait for all other CPU cores to complete the previous slice, such that they run in lock-step | 82 | // Wait for all other CPU cores to complete the previous slice, such that they run in lock-step |
| 70 | if (!cpu_barrier->Rendezvous()) { | 83 | if (!cpu_barrier->Rendezvous()) { |
diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h index 243f0b5e7..976952903 100644 --- a/src/core/core_cpu.h +++ b/src/core/core_cpu.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <mutex> | 10 | #include <mutex> |
| 11 | #include <string> | 11 | #include <string> |
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "core/arm/exclusive_monitor.h" | ||
| 13 | 14 | ||
| 14 | class ARM_Interface; | 15 | class ARM_Interface; |
| 15 | 16 | ||
| @@ -40,7 +41,8 @@ private: | |||
| 40 | 41 | ||
| 41 | class Cpu { | 42 | class Cpu { |
| 42 | public: | 43 | public: |
| 43 | Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index); | 44 | Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, |
| 45 | std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index); | ||
| 44 | 46 | ||
| 45 | void RunLoop(bool tight_loop = true); | 47 | void RunLoop(bool tight_loop = true); |
| 46 | 48 | ||
| @@ -64,6 +66,12 @@ public: | |||
| 64 | return core_index == 0; | 66 | return core_index == 0; |
| 65 | } | 67 | } |
| 66 | 68 | ||
| 69 | size_t CoreIndex() const { | ||
| 70 | return core_index; | ||
| 71 | } | ||
| 72 | |||
| 73 | static std::shared_ptr<ExclusiveMonitor> MakeExclusiveMonitor(size_t num_cores); | ||
| 74 | |||
| 67 | private: | 75 | private: |
| 68 | void Reschedule(); | 76 | void Reschedule(); |
| 69 | 77 | ||