2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

General: Add better safety for JIT use.

This commit is contained in:
Fernando Sahmkow 2020-02-27 19:12:41 -04:00
parent bd36eaf15d
commit 04e0f8776c
5 changed files with 39 additions and 7 deletions

View file

@ -6,6 +6,7 @@
#include <array> #include <array>
#include <vector> #include <vector>
#include <mutex>
#include "common/common_types.h" #include "common/common_types.h"
namespace Common { namespace Common {
@ -164,6 +165,14 @@ public:
std::string name; std::string name;
}; };
void Lock() {
guard.lock();
}
void Unlock() {
guard.unlock();
}
std::vector<BacktraceEntry> GetBacktrace() const; std::vector<BacktraceEntry> GetBacktrace() const;
/// fp (= r29) points to the last frame record. /// fp (= r29) points to the last frame record.
@ -178,6 +187,7 @@ protected:
/// System context that this ARM interface is running under. /// System context that this ARM interface is running under.
System& system; System& system;
CPUInterruptHandler& interrupt_handler; CPUInterruptHandler& interrupt_handler;
std::mutex guard;
}; };
} // namespace Core } // namespace Core

View file

@ -46,6 +46,11 @@ void CpuManager::GuestThreadFunction(void* cpu_manager_) {
cpu_manager->RunGuestThread(); cpu_manager->RunGuestThread();
} }
void CpuManager::GuestRewindFunction(void* cpu_manager_) {
CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
cpu_manager->RunGuestLoop();
}
void CpuManager::IdleThreadFunction(void* cpu_manager_) { void CpuManager::IdleThreadFunction(void* cpu_manager_) {
CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_); CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
cpu_manager->RunIdleThread(); cpu_manager->RunIdleThread();
@ -78,14 +83,22 @@ void CpuManager::RunGuestThread() {
auto& sched = kernel.CurrentScheduler(); auto& sched = kernel.CurrentScheduler();
sched.OnThreadStart(); sched.OnThreadStart();
} }
RunGuestLoop();
}
void CpuManager::RunGuestLoop() {
auto& kernel = system.Kernel();
auto* thread = kernel.CurrentScheduler().GetCurrentThread();
auto host_context = thread->GetHostContext();
host_context->SetRewindPoint(std::function<void(void*)>(GuestRewindFunction), this);
host_context.reset();
while (true) { while (true) {
auto* physical_core = &kernel.CurrentPhysicalCore(); auto& physical_core = kernel.CurrentPhysicalCore();
while (!physical_core->IsInterrupted()) { while (!physical_core.IsInterrupted()) {
physical_core->Run(); physical_core.Run();
physical_core = &kernel.CurrentPhysicalCore();
} }
physical_core->ClearExclusive(); physical_core.ClearExclusive();
auto& scheduler = physical_core->Scheduler(); auto& scheduler = physical_core.Scheduler();
scheduler.TryDoContextSwitch(); scheduler.TryDoContextSwitch();
} }
} }

View file

@ -42,10 +42,12 @@ public:
private: private:
static void GuestThreadFunction(void* cpu_manager); static void GuestThreadFunction(void* cpu_manager);
static void GuestRewindFunction(void* cpu_manager);
static void IdleThreadFunction(void* cpu_manager); static void IdleThreadFunction(void* cpu_manager);
static void SuspendThreadFunction(void* cpu_manager); static void SuspendThreadFunction(void* cpu_manager);
void RunGuestThread(); void RunGuestThread();
void RunGuestLoop();
void RunIdleThread(); void RunIdleThread();
void RunSuspendThread(); void RunSuspendThread();

View file

@ -581,6 +581,7 @@ void Scheduler::SwitchContextStep2() {
if (new_thread) { if (new_thread) {
new_thread->context_guard.lock(); new_thread->context_guard.lock();
cpu_core.Lock();
ASSERT_MSG(new_thread->GetProcessorID() == s32(this->core_id), ASSERT_MSG(new_thread->GetProcessorID() == s32(this->core_id),
"Thread must be assigned to this core."); "Thread must be assigned to this core.");
ASSERT_MSG(new_thread->GetStatus() == ThreadStatus::Ready, ASSERT_MSG(new_thread->GetStatus() == ThreadStatus::Ready,
@ -601,6 +602,7 @@ void Scheduler::SwitchContextStep2() {
cpu_core.LoadContext(new_thread->GetContext64()); cpu_core.LoadContext(new_thread->GetContext64());
cpu_core.SetTlsAddress(new_thread->GetTLSAddress()); cpu_core.SetTlsAddress(new_thread->GetTLSAddress());
cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0()); cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
cpu_core.ClearExclusiveState();
} }
} else { } else {
current_thread = nullptr; current_thread = nullptr;
@ -639,6 +641,7 @@ void Scheduler::SwitchContext() {
} }
previous_thread->SetIsRunning(false); previous_thread->SetIsRunning(false);
previous_thread->context_guard.unlock(); previous_thread->context_guard.unlock();
cpu_core.Unlock();
} }
std::shared_ptr<Common::Fiber> old_context; std::shared_ptr<Common::Fiber> old_context;

View file

@ -10,6 +10,7 @@
#include "common/alignment.h" #include "common/alignment.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/fiber.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/microprofile.h" #include "common/microprofile.h"
#include "common/string_util.h" #include "common/string_util.h"
@ -2468,7 +2469,10 @@ void Call(Core::System& system, u32 immediate) {
} }
auto& physical_core_2 = system.CurrentPhysicalCore(); auto& physical_core_2 = system.CurrentPhysicalCore();
if (physical_core.CoreIndex() != physical_core_2.CoreIndex()) { if (physical_core.CoreIndex() != physical_core_2.CoreIndex()) {
physical_core.Stop(); LOG_CRITICAL(Kernel_SVC, "Rewinding");
auto* thread = physical_core_2.Scheduler().GetCurrentThread();
auto* host_context = thread->GetHostContext().get();
host_context->Rewind();
} }
} }