From a58eefa7e42f156e4a9efead04c6d814286c2f10 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 25 Sep 2018 16:00:14 -0400
Subject: [PATCH 1/2] kernel/scheduler: Take ARM_Interface instance by
 reference in the constructor

It doesn't make sense to allow a scheduler to be constructed around a
null pointer.
---
 src/core/core_cpu.cpp             |  2 +-
 src/core/hle/kernel/scheduler.cpp | 14 +++++++-------
 src/core/hle/kernel/scheduler.h   |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 21568ad50a..0140e97133 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -64,7 +64,7 @@ Cpu::Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor,
         arm_interface = std::make_shared<ARM_Unicorn>();
     }
 
-    scheduler = std::make_shared<Kernel::Scheduler>(arm_interface.get());
+    scheduler = std::make_shared<Kernel::Scheduler>(*arm_interface);
 }
 
 Cpu::~Cpu() = default;
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 69c812f16b..9faf903cf7 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -17,7 +17,7 @@ namespace Kernel {
 
 std::mutex Scheduler::scheduler_mutex;
 
-Scheduler::Scheduler(Core::ARM_Interface* cpu_core) : cpu_core(cpu_core) {}
+Scheduler::Scheduler(Core::ARM_Interface& cpu_core) : cpu_core(cpu_core) {}
 
 Scheduler::~Scheduler() {
     for (auto& thread : thread_list) {
@@ -59,9 +59,9 @@ void Scheduler::SwitchContext(Thread* new_thread) {
     // Save context for previous thread
     if (previous_thread) {
         previous_thread->last_running_ticks = CoreTiming::GetTicks();
-        cpu_core->SaveContext(previous_thread->context);
+        cpu_core.SaveContext(previous_thread->context);
         // Save the TPIDR_EL0 system register in case it was modified.
-        previous_thread->tpidr_el0 = cpu_core->GetTPIDR_EL0();
+        previous_thread->tpidr_el0 = cpu_core.GetTPIDR_EL0();
 
         if (previous_thread->status == ThreadStatus::Running) {
             // This is only the case when a reschedule is triggered without the current thread
@@ -91,10 +91,10 @@ void Scheduler::SwitchContext(Thread* new_thread) {
             SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
         }
 
-        cpu_core->LoadContext(new_thread->context);
-        cpu_core->SetTlsAddress(new_thread->GetTLSAddress());
-        cpu_core->SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
-        cpu_core->ClearExclusiveState();
+        cpu_core.LoadContext(new_thread->context);
+        cpu_core.SetTlsAddress(new_thread->GetTLSAddress());
+        cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
+        cpu_core.ClearExclusiveState();
     } else {
         current_thread = nullptr;
         // Note: We do not reset the current process and current page table when idling because
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h
index 744990c9b6..2c94641ecd 100644
--- a/src/core/hle/kernel/scheduler.h
+++ b/src/core/hle/kernel/scheduler.h
@@ -19,7 +19,7 @@ namespace Kernel {
 
 class Scheduler final {
 public:
-    explicit Scheduler(Core::ARM_Interface* cpu_core);
+    explicit Scheduler(Core::ARM_Interface& cpu_core);
     ~Scheduler();
 
     /// Returns whether there are any threads that are ready to run.
@@ -72,7 +72,7 @@ private:
 
     SharedPtr<Thread> current_thread = nullptr;
 
-    Core::ARM_Interface* cpu_core;
+    Core::ARM_Interface& cpu_core;
 
     static std::mutex scheduler_mutex;
 };

From 598e4d2f6ccfc3dc774a28be53d8b1d78ebbd08d Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 25 Sep 2018 16:04:53 -0400
Subject: [PATCH 2/2] core_cpu: Make arm_interface instances a std::unique_ptr

This is only exposed by reference, so we can just make it a unique
pointer to get rid of the need to also use reference counting for the
pointer.
---
 src/core/core_cpu.cpp | 6 +++---
 src/core/core_cpu.h   | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 0140e97133..265f8ed9cc 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -55,13 +55,13 @@ Cpu::Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor,
 
     if (Settings::values.use_cpu_jit) {
 #ifdef ARCHITECTURE_x86_64
-        arm_interface = std::make_shared<ARM_Dynarmic>(exclusive_monitor, core_index);
+        arm_interface = std::make_unique<ARM_Dynarmic>(exclusive_monitor, core_index);
 #else
-        arm_interface = std::make_shared<ARM_Unicorn>();
+        arm_interface = std::make_unique<ARM_Unicorn>();
         LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
 #endif
     } else {
-        arm_interface = std::make_shared<ARM_Unicorn>();
+        arm_interface = std::make_unique<ARM_Unicorn>();
     }
 
     scheduler = std::make_shared<Kernel::Scheduler>(*arm_interface);
diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h
index 6855329654..ee7e04abc8 100644
--- a/src/core/core_cpu.h
+++ b/src/core/core_cpu.h
@@ -76,7 +76,7 @@ public:
 private:
     void Reschedule();
 
-    std::shared_ptr<ARM_Interface> arm_interface;
+    std::unique_ptr<ARM_Interface> arm_interface;
     std::shared_ptr<CpuBarrier> cpu_barrier;
     std::shared_ptr<Kernel::Scheduler> scheduler;