summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp5
-rw-r--r--src/core/core.cpp15
-rw-r--r--src/core/core.h6
-rw-r--r--src/core/cpu_manager.cpp4
-rw-r--r--src/core/hle/kernel/kernel.cpp15
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/scheduler.cpp7
-rw-r--r--src/core/hle/kernel/svc.cpp10
-rw-r--r--src/core/hle/kernel/thread.h18
-rw-r--r--src/yuzu/debugger/wait_tree.cpp12
11 files changed, 87 insertions, 13 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 30bf62ac1..618f02f30 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -7,7 +7,6 @@
7#include <dynarmic/A32/a32.h> 7#include <dynarmic/A32/a32.h>
8#include <dynarmic/A32/config.h> 8#include <dynarmic/A32/config.h>
9#include <dynarmic/A32/context.h> 9#include <dynarmic/A32/context.h>
10#include "common/microprofile.h"
11#include "core/arm/cpu_interrupt_handler.h" 10#include "core/arm/cpu_interrupt_handler.h"
12#include "core/arm/dynarmic/arm_dynarmic_32.h" 11#include "core/arm/dynarmic/arm_dynarmic_32.h"
13#include "core/arm/dynarmic/arm_dynarmic_64.h" 12#include "core/arm/dynarmic/arm_dynarmic_64.h"
@@ -97,10 +96,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
97 return std::make_unique<Dynarmic::A32::Jit>(config); 96 return std::make_unique<Dynarmic::A32::Jit>(config);
98} 97}
99 98
100MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_32, "ARM JIT", "Dynarmic", MP_RGB(255, 64, 64));
101
102void ARM_Dynarmic_32::Run() { 99void ARM_Dynarmic_32::Run() {
103 MICROPROFILE_SCOPE(ARM_Jit_Dynarmic_32);
104 jit->Run(); 100 jit->Run();
105} 101}
106 102
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index a22c22bf0..84b872f0b 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -7,7 +7,6 @@
7#include <dynarmic/A64/a64.h> 7#include <dynarmic/A64/a64.h>
8#include <dynarmic/A64/config.h> 8#include <dynarmic/A64/config.h>
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/microprofile.h"
11#include "common/page_table.h" 10#include "common/page_table.h"
12#include "core/arm/cpu_interrupt_handler.h" 11#include "core/arm/cpu_interrupt_handler.h"
13#include "core/arm/dynarmic/arm_dynarmic_64.h" 12#include "core/arm/dynarmic/arm_dynarmic_64.h"
@@ -181,11 +180,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
181 return std::make_shared<Dynarmic::A64::Jit>(config); 180 return std::make_shared<Dynarmic::A64::Jit>(config);
182} 181}
183 182
184MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_64, "ARM JIT", "Dynarmic", MP_RGB(255, 64, 64));
185 183
186void ARM_Dynarmic_64::Run() {
187 MICROPROFILE_SCOPE(ARM_Jit_Dynarmic_64);
188 184
185void ARM_Dynarmic_64::Run() {
189 jit->Run(); 186 jit->Run();
190} 187}
191 188
diff --git a/src/core/core.cpp b/src/core/core.cpp
index fd1bdcaf0..032da7aa5 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -8,6 +8,7 @@
8 8
9#include "common/file_util.h" 9#include "common/file_util.h"
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "common/microprofile.h"
11#include "common/string_util.h" 12#include "common/string_util.h"
12#include "core/arm/exclusive_monitor.h" 13#include "core/arm/exclusive_monitor.h"
13#include "core/core.h" 14#include "core/core.h"
@@ -50,6 +51,8 @@
50#include "video_core/renderer_base.h" 51#include "video_core/renderer_base.h"
51#include "video_core/video_core.h" 52#include "video_core/video_core.h"
52 53
54MICROPROFILE_DEFINE(ARM_Jit_Dynarmic, "ARM JIT", "Dynarmic", MP_RGB(255, 64, 64));
55
53namespace Core { 56namespace Core {
54 57
55namespace { 58namespace {
@@ -391,6 +394,8 @@ struct System::Impl {
391 394
392 std::unique_ptr<Core::PerfStats> perf_stats; 395 std::unique_ptr<Core::PerfStats> perf_stats;
393 Core::FrameLimiter frame_limiter; 396 Core::FrameLimiter frame_limiter;
397
398 std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
394}; 399};
395 400
396System::System() : impl{std::make_unique<Impl>(*this)} {} 401System::System() : impl{std::make_unique<Impl>(*this)} {}
@@ -736,4 +741,14 @@ void System::RegisterHostThread() {
736 impl->kernel.RegisterHostThread(); 741 impl->kernel.RegisterHostThread();
737} 742}
738 743
744void System::EnterDynarmicProfile() {
745 std::size_t core = impl->kernel.GetCurrentHostThreadID();
746 impl->dynarmic_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(ARM_Jit_Dynarmic));
747}
748
749void System::ExitDynarmicProfile() {
750 std::size_t core = impl->kernel.GetCurrentHostThreadID();
751 MicroProfileLeave(MICROPROFILE_TOKEN(ARM_Jit_Dynarmic), impl->dynarmic_ticks[core]);
752}
753
739} // namespace Core 754} // namespace Core
diff --git a/src/core/core.h b/src/core/core.h
index 9a0dd1075..87df79d57 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -377,6 +377,12 @@ public:
377 /// Register a host thread as an auxiliary thread. 377 /// Register a host thread as an auxiliary thread.
378 void RegisterHostThread(); 378 void RegisterHostThread();
379 379
380 /// Enter Dynarmic Microprofile
381 void EnterDynarmicProfile();
382
383 /// Exit Dynarmic Microprofile
384 void ExitDynarmicProfile();
385
380private: 386private:
381 System(); 387 System();
382 388
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 95842aad1..9e2e6d49f 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -118,9 +118,11 @@ void CpuManager::MultiCoreRunGuestLoop() {
118 host_context.reset(); 118 host_context.reset();
119 while (true) { 119 while (true) {
120 auto& physical_core = kernel.CurrentPhysicalCore(); 120 auto& physical_core = kernel.CurrentPhysicalCore();
121 system.EnterDynarmicProfile();
121 while (!physical_core.IsInterrupted()) { 122 while (!physical_core.IsInterrupted()) {
122 physical_core.Run(); 123 physical_core.Run();
123 } 124 }
125 system.ExitDynarmicProfile();
124 physical_core.ClearExclusive(); 126 physical_core.ClearExclusive();
125 auto& scheduler = physical_core.Scheduler(); 127 auto& scheduler = physical_core.Scheduler();
126 scheduler.TryDoContextSwitch(); 128 scheduler.TryDoContextSwitch();
@@ -216,6 +218,7 @@ void CpuManager::SingleCoreRunGuestLoop() {
216 host_context.reset(); 218 host_context.reset();
217 while (true) { 219 while (true) {
218 auto& physical_core = kernel.CurrentPhysicalCore(); 220 auto& physical_core = kernel.CurrentPhysicalCore();
221 system.EnterDynarmicProfile();
219 while (!physical_core.IsInterrupted()) { 222 while (!physical_core.IsInterrupted()) {
220 physical_core.Run(); 223 physical_core.Run();
221 preemption_count++; 224 preemption_count++;
@@ -224,6 +227,7 @@ void CpuManager::SingleCoreRunGuestLoop() {
224 } 227 }
225 } 228 }
226 physical_core.ClearExclusive(); 229 physical_core.ClearExclusive();
230 system.ExitDynarmicProfile();
227 PreemptSingleCore(); 231 PreemptSingleCore();
228 auto& scheduler = kernel.Scheduler(current_core); 232 auto& scheduler = kernel.Scheduler(current_core);
229 scheduler.TryDoContextSwitch(); 233 scheduler.TryDoContextSwitch();
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 24da4367e..d2f5f9bf2 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -13,6 +13,7 @@
13 13
14#include "common/assert.h" 14#include "common/assert.h"
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "common/microprofile.h"
16#include "common/thread.h" 17#include "common/thread.h"
17#include "core/arm/arm_interface.h" 18#include "core/arm/arm_interface.h"
18#include "core/arm/exclusive_monitor.h" 19#include "core/arm/exclusive_monitor.h"
@@ -41,6 +42,8 @@
41#include "core/hle/result.h" 42#include "core/hle/result.h"
42#include "core/memory.h" 43#include "core/memory.h"
43 44
45MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
46
44namespace Kernel { 47namespace Kernel {
45 48
46/** 49/**
@@ -408,6 +411,8 @@ struct KernelCore::Impl {
408 bool is_multicore{}; 411 bool is_multicore{};
409 std::thread::id single_core_thread_id{}; 412 std::thread::id single_core_thread_id{};
410 413
414 std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{};
415
411 // System context 416 // System context
412 Core::System& system; 417 Core::System& system;
413}; 418};
@@ -666,4 +671,14 @@ void KernelCore::ExceptionalExit() {
666 Suspend(true); 671 Suspend(true);
667} 672}
668 673
674void KernelCore::EnterSVCProfile() {
675 std::size_t core = impl->GetCurrentHostThreadID();
676 impl->svc_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
677}
678
679void KernelCore::ExitSVCProfile() {
680 std::size_t core = impl->GetCurrentHostThreadID();
681 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]);
682}
683
669} // namespace Kernel 684} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 50eeb50ec..1eb6ede73 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -214,6 +214,10 @@ public:
214 214
215 bool IsMulticore() const; 215 bool IsMulticore() const;
216 216
217 void EnterSVCProfile();
218
219 void ExitSVCProfile();
220
217private: 221private:
218 friend class Object; 222 friend class Object;
219 friend class Process; 223 friend class Process;
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 25fc8a3e8..2ad380b17 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -354,7 +354,9 @@ void GlobalScheduler::EnableInterruptAndSchedule(u32 cores_pending_reschedule,
354 } 354 }
355 if (must_context_switch) { 355 if (must_context_switch) {
356 auto& core_scheduler = kernel.CurrentScheduler(); 356 auto& core_scheduler = kernel.CurrentScheduler();
357 kernel.ExitSVCProfile();
357 core_scheduler.TryDoContextSwitch(); 358 core_scheduler.TryDoContextSwitch();
359 kernel.EnterSVCProfile();
358 } 360 }
359} 361}
360 362
@@ -628,6 +630,7 @@ void Scheduler::Reload() {
628 630
629 // Cancel any outstanding wakeup events for this thread 631 // Cancel any outstanding wakeup events for this thread
630 thread->SetIsRunning(true); 632 thread->SetIsRunning(true);
633 thread->SetWasRunning(false);
631 thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); 634 thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
632 635
633 auto* const thread_owner_process = thread->GetOwnerProcess(); 636 auto* const thread_owner_process = thread->GetOwnerProcess();
@@ -660,6 +663,7 @@ void Scheduler::SwitchContextStep2() {
660 // Cancel any outstanding wakeup events for this thread 663 // Cancel any outstanding wakeup events for this thread
661 new_thread->SetIsRunning(true); 664 new_thread->SetIsRunning(true);
662 new_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); 665 new_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
666 new_thread->SetWasRunning(false);
663 667
664 auto* const thread_owner_process = current_thread->GetOwnerProcess(); 668 auto* const thread_owner_process = current_thread->GetOwnerProcess();
665 if (previous_process != thread_owner_process && thread_owner_process != nullptr) { 669 if (previous_process != thread_owner_process && thread_owner_process != nullptr) {
@@ -698,6 +702,9 @@ void Scheduler::SwitchContext() {
698 702
699 // Save context for previous thread 703 // Save context for previous thread
700 if (previous_thread) { 704 if (previous_thread) {
705 if (new_thread != nullptr && new_thread->IsSuspendThread()) {
706 previous_thread->SetWasRunning(true);
707 }
701 previous_thread->SetContinuousOnSVC(false); 708 previous_thread->SetContinuousOnSVC(false);
702 previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); 709 previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
703 if (!previous_thread->IsHLEThread()) { 710 if (!previous_thread->IsHLEThread()) {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index d3d4e7bf9..9b9f9402e 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2454,10 +2454,10 @@ static const FunctionDef* GetSVCInfo64(u32 func_num) {
2454 return &SVC_Table_64[func_num]; 2454 return &SVC_Table_64[func_num];
2455} 2455}
2456 2456
2457MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
2458
2459void Call(Core::System& system, u32 immediate) { 2457void Call(Core::System& system, u32 immediate) {
2460 MICROPROFILE_SCOPE(Kernel_SVC); 2458 system.ExitDynarmicProfile();
2459 auto& kernel = system.Kernel();
2460 kernel.EnterSVCProfile();
2461 2461
2462 auto* thread = system.CurrentScheduler().GetCurrentThread(); 2462 auto* thread = system.CurrentScheduler().GetCurrentThread();
2463 thread->SetContinuousOnSVC(true); 2463 thread->SetContinuousOnSVC(true);
@@ -2474,10 +2474,14 @@ void Call(Core::System& system, u32 immediate) {
2474 LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate); 2474 LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate);
2475 } 2475 }
2476 2476
2477 kernel.ExitSVCProfile();
2478
2477 if (!thread->IsContinuousOnSVC()) { 2479 if (!thread->IsContinuousOnSVC()) {
2478 auto* host_context = thread->GetHostContext().get(); 2480 auto* host_context = thread->GetHostContext().get();
2479 host_context->Rewind(); 2481 host_context->Rewind();
2480 } 2482 }
2483
2484 system.EnterDynarmicProfile();
2481} 2485}
2482 2486
2483} // namespace Kernel::Svc 2487} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 168828ab0..f42d7bd13 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -350,6 +350,22 @@ public:
350 return (type & THREADTYPE_HLE) != 0; 350 return (type & THREADTYPE_HLE) != 0;
351 } 351 }
352 352
353 bool IsSuspendThread() const {
354 return (type & THREADTYPE_SUSPEND) != 0;
355 }
356
357 bool IsIdleThread() const {
358 return (type & THREADTYPE_IDLE) != 0;
359 }
360
361 bool WasRunning() const {
362 return was_running;
363 }
364
365 void SetWasRunning(bool value) {
366 was_running = value;
367 }
368
353 std::shared_ptr<Common::Fiber> GetHostContext() const; 369 std::shared_ptr<Common::Fiber> GetHostContext() const;
354 370
355 ThreadStatus GetStatus() const { 371 ThreadStatus GetStatus() const {
@@ -684,6 +700,8 @@ private:
684 700
685 bool will_be_terminated = false; 701 bool will_be_terminated = false;
686 702
703 bool was_running = false;
704
687 std::string name; 705 std::string name;
688}; 706};
689 707
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index ab7b18abe..fa091f457 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -209,7 +209,11 @@ QString WaitTreeThread::GetText() const {
209 break; 209 break;
210 case Kernel::ThreadStatus::Ready: 210 case Kernel::ThreadStatus::Ready:
211 if (!thread.IsPaused()) { 211 if (!thread.IsPaused()) {
212 status = tr("ready"); 212 if (thread.WasRunning()) {
213 status = tr("running");
214 } else {
215 status = tr("ready");
216 }
213 } else { 217 } else {
214 status = tr("paused"); 218 status = tr("paused");
215 } 219 }
@@ -261,7 +265,11 @@ QColor WaitTreeThread::GetColor() const {
261 return QColor(Qt::GlobalColor::darkGreen); 265 return QColor(Qt::GlobalColor::darkGreen);
262 case Kernel::ThreadStatus::Ready: 266 case Kernel::ThreadStatus::Ready:
263 if (!thread.IsPaused()) { 267 if (!thread.IsPaused()) {
264 return QColor(Qt::GlobalColor::darkBlue); 268 if (thread.WasRunning()) {
269 return QColor(Qt::GlobalColor::darkGreen);
270 } else {
271 return QColor(Qt::GlobalColor::darkBlue);
272 }
265 } else { 273 } else {
266 return QColor(Qt::GlobalColor::lightGray); 274 return QColor(Qt::GlobalColor::lightGray);
267 } 275 }