General: Fix microprofile on dynarmic/svc, fix wait tree showing which threads were running.
This commit is contained in:
parent
e6f8bde74b
commit
7020d498c5
11 changed files with 87 additions and 13 deletions
|
@ -7,7 +7,6 @@
|
||||||
#include <dynarmic/A32/a32.h>
|
#include <dynarmic/A32/a32.h>
|
||||||
#include <dynarmic/A32/config.h>
|
#include <dynarmic/A32/config.h>
|
||||||
#include <dynarmic/A32/context.h>
|
#include <dynarmic/A32/context.h>
|
||||||
#include "common/microprofile.h"
|
|
||||||
#include "core/arm/cpu_interrupt_handler.h"
|
#include "core/arm/cpu_interrupt_handler.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_32.h"
|
#include "core/arm/dynarmic/arm_dynarmic_32.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
||||||
|
@ -97,10 +96,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
|
||||||
return std::make_unique<Dynarmic::A32::Jit>(config);
|
return std::make_unique<Dynarmic::A32::Jit>(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_32, "ARM JIT", "Dynarmic", MP_RGB(255, 64, 64));
|
|
||||||
|
|
||||||
void ARM_Dynarmic_32::Run() {
|
void ARM_Dynarmic_32::Run() {
|
||||||
MICROPROFILE_SCOPE(ARM_Jit_Dynarmic_32);
|
|
||||||
jit->Run();
|
jit->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <dynarmic/A64/a64.h>
|
#include <dynarmic/A64/a64.h>
|
||||||
#include <dynarmic/A64/config.h>
|
#include <dynarmic/A64/config.h>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
|
||||||
#include "common/page_table.h"
|
#include "common/page_table.h"
|
||||||
#include "core/arm/cpu_interrupt_handler.h"
|
#include "core/arm/cpu_interrupt_handler.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
||||||
|
@ -181,11 +180,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
|
||||||
return std::make_shared<Dynarmic::A64::Jit>(config);
|
return std::make_shared<Dynarmic::A64::Jit>(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_64, "ARM JIT", "Dynarmic", MP_RGB(255, 64, 64));
|
|
||||||
|
|
||||||
void ARM_Dynarmic_64::Run() {
|
void ARM_Dynarmic_64::Run() {
|
||||||
MICROPROFILE_SCOPE(ARM_Jit_Dynarmic_64);
|
|
||||||
|
|
||||||
jit->Run();
|
jit->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/microprofile.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/arm/exclusive_monitor.h"
|
#include "core/arm/exclusive_monitor.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -50,6 +51,8 @@
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
|
MICROPROFILE_DEFINE(ARM_Jit_Dynarmic, "ARM JIT", "Dynarmic", MP_RGB(255, 64, 64));
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -391,6 +394,8 @@ struct System::Impl {
|
||||||
|
|
||||||
std::unique_ptr<Core::PerfStats> perf_stats;
|
std::unique_ptr<Core::PerfStats> perf_stats;
|
||||||
Core::FrameLimiter frame_limiter;
|
Core::FrameLimiter frame_limiter;
|
||||||
|
|
||||||
|
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
|
||||||
};
|
};
|
||||||
|
|
||||||
System::System() : impl{std::make_unique<Impl>(*this)} {}
|
System::System() : impl{std::make_unique<Impl>(*this)} {}
|
||||||
|
@ -736,4 +741,14 @@ void System::RegisterHostThread() {
|
||||||
impl->kernel.RegisterHostThread();
|
impl->kernel.RegisterHostThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void System::EnterDynarmicProfile() {
|
||||||
|
std::size_t core = impl->kernel.GetCurrentHostThreadID();
|
||||||
|
impl->dynarmic_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(ARM_Jit_Dynarmic));
|
||||||
|
}
|
||||||
|
|
||||||
|
void System::ExitDynarmicProfile() {
|
||||||
|
std::size_t core = impl->kernel.GetCurrentHostThreadID();
|
||||||
|
MicroProfileLeave(MICROPROFILE_TOKEN(ARM_Jit_Dynarmic), impl->dynarmic_ticks[core]);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -377,6 +377,12 @@ public:
|
||||||
/// Register a host thread as an auxiliary thread.
|
/// Register a host thread as an auxiliary thread.
|
||||||
void RegisterHostThread();
|
void RegisterHostThread();
|
||||||
|
|
||||||
|
/// Enter Dynarmic Microprofile
|
||||||
|
void EnterDynarmicProfile();
|
||||||
|
|
||||||
|
/// Exit Dynarmic Microprofile
|
||||||
|
void ExitDynarmicProfile();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
System();
|
System();
|
||||||
|
|
||||||
|
|
|
@ -118,9 +118,11 @@ void CpuManager::MultiCoreRunGuestLoop() {
|
||||||
host_context.reset();
|
host_context.reset();
|
||||||
while (true) {
|
while (true) {
|
||||||
auto& physical_core = kernel.CurrentPhysicalCore();
|
auto& physical_core = kernel.CurrentPhysicalCore();
|
||||||
|
system.EnterDynarmicProfile();
|
||||||
while (!physical_core.IsInterrupted()) {
|
while (!physical_core.IsInterrupted()) {
|
||||||
physical_core.Run();
|
physical_core.Run();
|
||||||
}
|
}
|
||||||
|
system.ExitDynarmicProfile();
|
||||||
physical_core.ClearExclusive();
|
physical_core.ClearExclusive();
|
||||||
auto& scheduler = physical_core.Scheduler();
|
auto& scheduler = physical_core.Scheduler();
|
||||||
scheduler.TryDoContextSwitch();
|
scheduler.TryDoContextSwitch();
|
||||||
|
@ -216,6 +218,7 @@ void CpuManager::SingleCoreRunGuestLoop() {
|
||||||
host_context.reset();
|
host_context.reset();
|
||||||
while (true) {
|
while (true) {
|
||||||
auto& physical_core = kernel.CurrentPhysicalCore();
|
auto& physical_core = kernel.CurrentPhysicalCore();
|
||||||
|
system.EnterDynarmicProfile();
|
||||||
while (!physical_core.IsInterrupted()) {
|
while (!physical_core.IsInterrupted()) {
|
||||||
physical_core.Run();
|
physical_core.Run();
|
||||||
preemption_count++;
|
preemption_count++;
|
||||||
|
@ -224,6 +227,7 @@ void CpuManager::SingleCoreRunGuestLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
physical_core.ClearExclusive();
|
physical_core.ClearExclusive();
|
||||||
|
system.ExitDynarmicProfile();
|
||||||
PreemptSingleCore();
|
PreemptSingleCore();
|
||||||
auto& scheduler = kernel.Scheduler(current_core);
|
auto& scheduler = kernel.Scheduler(current_core);
|
||||||
scheduler.TryDoContextSwitch();
|
scheduler.TryDoContextSwitch();
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/microprofile.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/arm/exclusive_monitor.h"
|
#include "core/arm/exclusive_monitor.h"
|
||||||
|
@ -41,6 +42,8 @@
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -408,6 +411,8 @@ struct KernelCore::Impl {
|
||||||
bool is_multicore{};
|
bool is_multicore{};
|
||||||
std::thread::id single_core_thread_id{};
|
std::thread::id single_core_thread_id{};
|
||||||
|
|
||||||
|
std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{};
|
||||||
|
|
||||||
// System context
|
// System context
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
@ -666,4 +671,14 @@ void KernelCore::ExceptionalExit() {
|
||||||
Suspend(true);
|
Suspend(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KernelCore::EnterSVCProfile() {
|
||||||
|
std::size_t core = impl->GetCurrentHostThreadID();
|
||||||
|
impl->svc_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernelCore::ExitSVCProfile() {
|
||||||
|
std::size_t core = impl->GetCurrentHostThreadID();
|
||||||
|
MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -214,6 +214,10 @@ public:
|
||||||
|
|
||||||
bool IsMulticore() const;
|
bool IsMulticore() const;
|
||||||
|
|
||||||
|
void EnterSVCProfile();
|
||||||
|
|
||||||
|
void ExitSVCProfile();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Object;
|
friend class Object;
|
||||||
friend class Process;
|
friend class Process;
|
||||||
|
|
|
@ -354,7 +354,9 @@ void GlobalScheduler::EnableInterruptAndSchedule(u32 cores_pending_reschedule,
|
||||||
}
|
}
|
||||||
if (must_context_switch) {
|
if (must_context_switch) {
|
||||||
auto& core_scheduler = kernel.CurrentScheduler();
|
auto& core_scheduler = kernel.CurrentScheduler();
|
||||||
|
kernel.ExitSVCProfile();
|
||||||
core_scheduler.TryDoContextSwitch();
|
core_scheduler.TryDoContextSwitch();
|
||||||
|
kernel.EnterSVCProfile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,6 +630,7 @@ void Scheduler::Reload() {
|
||||||
|
|
||||||
// Cancel any outstanding wakeup events for this thread
|
// Cancel any outstanding wakeup events for this thread
|
||||||
thread->SetIsRunning(true);
|
thread->SetIsRunning(true);
|
||||||
|
thread->SetWasRunning(false);
|
||||||
thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
|
thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
|
||||||
|
|
||||||
auto* const thread_owner_process = thread->GetOwnerProcess();
|
auto* const thread_owner_process = thread->GetOwnerProcess();
|
||||||
|
@ -660,6 +663,7 @@ void Scheduler::SwitchContextStep2() {
|
||||||
// Cancel any outstanding wakeup events for this thread
|
// Cancel any outstanding wakeup events for this thread
|
||||||
new_thread->SetIsRunning(true);
|
new_thread->SetIsRunning(true);
|
||||||
new_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
|
new_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
|
||||||
|
new_thread->SetWasRunning(false);
|
||||||
|
|
||||||
auto* const thread_owner_process = current_thread->GetOwnerProcess();
|
auto* const thread_owner_process = current_thread->GetOwnerProcess();
|
||||||
if (previous_process != thread_owner_process && thread_owner_process != nullptr) {
|
if (previous_process != thread_owner_process && thread_owner_process != nullptr) {
|
||||||
|
@ -698,6 +702,9 @@ void Scheduler::SwitchContext() {
|
||||||
|
|
||||||
// Save context for previous thread
|
// Save context for previous thread
|
||||||
if (previous_thread) {
|
if (previous_thread) {
|
||||||
|
if (new_thread != nullptr && new_thread->IsSuspendThread()) {
|
||||||
|
previous_thread->SetWasRunning(true);
|
||||||
|
}
|
||||||
previous_thread->SetContinuousOnSVC(false);
|
previous_thread->SetContinuousOnSVC(false);
|
||||||
previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
|
previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
|
||||||
if (!previous_thread->IsHLEThread()) {
|
if (!previous_thread->IsHLEThread()) {
|
||||||
|
|
|
@ -2454,10 +2454,10 @@ static const FunctionDef* GetSVCInfo64(u32 func_num) {
|
||||||
return &SVC_Table_64[func_num];
|
return &SVC_Table_64[func_num];
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
|
||||||
|
|
||||||
void Call(Core::System& system, u32 immediate) {
|
void Call(Core::System& system, u32 immediate) {
|
||||||
MICROPROFILE_SCOPE(Kernel_SVC);
|
system.ExitDynarmicProfile();
|
||||||
|
auto& kernel = system.Kernel();
|
||||||
|
kernel.EnterSVCProfile();
|
||||||
|
|
||||||
auto* thread = system.CurrentScheduler().GetCurrentThread();
|
auto* thread = system.CurrentScheduler().GetCurrentThread();
|
||||||
thread->SetContinuousOnSVC(true);
|
thread->SetContinuousOnSVC(true);
|
||||||
|
@ -2474,10 +2474,14 @@ void Call(Core::System& system, u32 immediate) {
|
||||||
LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate);
|
LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kernel.ExitSVCProfile();
|
||||||
|
|
||||||
if (!thread->IsContinuousOnSVC()) {
|
if (!thread->IsContinuousOnSVC()) {
|
||||||
auto* host_context = thread->GetHostContext().get();
|
auto* host_context = thread->GetHostContext().get();
|
||||||
host_context->Rewind();
|
host_context->Rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
system.EnterDynarmicProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Kernel::Svc
|
} // namespace Kernel::Svc
|
||||||
|
|
|
@ -350,6 +350,22 @@ public:
|
||||||
return (type & THREADTYPE_HLE) != 0;
|
return (type & THREADTYPE_HLE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsSuspendThread() const {
|
||||||
|
return (type & THREADTYPE_SUSPEND) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsIdleThread() const {
|
||||||
|
return (type & THREADTYPE_IDLE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WasRunning() const {
|
||||||
|
return was_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWasRunning(bool value) {
|
||||||
|
was_running = value;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<Common::Fiber> GetHostContext() const;
|
std::shared_ptr<Common::Fiber> GetHostContext() const;
|
||||||
|
|
||||||
ThreadStatus GetStatus() const {
|
ThreadStatus GetStatus() const {
|
||||||
|
@ -684,6 +700,8 @@ private:
|
||||||
|
|
||||||
bool will_be_terminated = false;
|
bool will_be_terminated = false;
|
||||||
|
|
||||||
|
bool was_running = false;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,11 @@ QString WaitTreeThread::GetText() const {
|
||||||
break;
|
break;
|
||||||
case Kernel::ThreadStatus::Ready:
|
case Kernel::ThreadStatus::Ready:
|
||||||
if (!thread.IsPaused()) {
|
if (!thread.IsPaused()) {
|
||||||
|
if (thread.WasRunning()) {
|
||||||
|
status = tr("running");
|
||||||
|
} else {
|
||||||
status = tr("ready");
|
status = tr("ready");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
status = tr("paused");
|
status = tr("paused");
|
||||||
}
|
}
|
||||||
|
@ -261,7 +265,11 @@ QColor WaitTreeThread::GetColor() const {
|
||||||
return QColor(Qt::GlobalColor::darkGreen);
|
return QColor(Qt::GlobalColor::darkGreen);
|
||||||
case Kernel::ThreadStatus::Ready:
|
case Kernel::ThreadStatus::Ready:
|
||||||
if (!thread.IsPaused()) {
|
if (!thread.IsPaused()) {
|
||||||
|
if (thread.WasRunning()) {
|
||||||
|
return QColor(Qt::GlobalColor::darkGreen);
|
||||||
|
} else {
|
||||||
return QColor(Qt::GlobalColor::darkBlue);
|
return QColor(Qt::GlobalColor::darkBlue);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return QColor(Qt::GlobalColor::lightGray);
|
return QColor(Qt::GlobalColor::lightGray);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue