summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2020-03-12 21:48:43 +0100
committerFernando Sahmkow <fsahmkow27@gmail.com>2020-06-27 17:35:48 +0200
commit7020d498c5aef7c1180bfc57031cdd7fbfecdf0f (patch)
treef2508e39a02966cdd4d9acda1e14ed93cdc150cd /src/core/hle/kernel
parentGeneral: Fix Stop function (diff)
downloadyuzu-7020d498c5aef7c1180bfc57031cdd7fbfecdf0f.tar
yuzu-7020d498c5aef7c1180bfc57031cdd7fbfecdf0f.tar.gz
yuzu-7020d498c5aef7c1180bfc57031cdd7fbfecdf0f.tar.bz2
yuzu-7020d498c5aef7c1180bfc57031cdd7fbfecdf0f.tar.lz
yuzu-7020d498c5aef7c1180bfc57031cdd7fbfecdf0f.tar.xz
yuzu-7020d498c5aef7c1180bfc57031cdd7fbfecdf0f.tar.zst
yuzu-7020d498c5aef7c1180bfc57031cdd7fbfecdf0f.zip
Diffstat (limited to 'src/core/hle/kernel')
-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
5 files changed, 51 insertions, 3 deletions
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 @@
#include "common/assert.h"
#include "common/logging/log.h"
+#include "common/microprofile.h"
#include "common/thread.h"
#include "core/arm/arm_interface.h"
#include "core/arm/exclusive_monitor.h"
@@ -41,6 +42,8 @@
#include "core/hle/result.h"
#include "core/memory.h"
+MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
+
namespace Kernel {
/**
@@ -408,6 +411,8 @@ struct KernelCore::Impl {
bool is_multicore{};
std::thread::id single_core_thread_id{};
+ std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{};
+
// System context
Core::System& system;
};
@@ -666,4 +671,14 @@ void KernelCore::ExceptionalExit() {
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
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:
bool IsMulticore() const;
+ void EnterSVCProfile();
+
+ void ExitSVCProfile();
+
private:
friend class Object;
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,
}
if (must_context_switch) {
auto& core_scheduler = kernel.CurrentScheduler();
+ kernel.ExitSVCProfile();
core_scheduler.TryDoContextSwitch();
+ kernel.EnterSVCProfile();
}
}
@@ -628,6 +630,7 @@ void Scheduler::Reload() {
// Cancel any outstanding wakeup events for this thread
thread->SetIsRunning(true);
+ thread->SetWasRunning(false);
thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
auto* const thread_owner_process = thread->GetOwnerProcess();
@@ -660,6 +663,7 @@ void Scheduler::SwitchContextStep2() {
// Cancel any outstanding wakeup events for this thread
new_thread->SetIsRunning(true);
new_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
+ new_thread->SetWasRunning(false);
auto* const thread_owner_process = current_thread->GetOwnerProcess();
if (previous_process != thread_owner_process && thread_owner_process != nullptr) {
@@ -698,6 +702,9 @@ void Scheduler::SwitchContext() {
// Save context for previous thread
if (previous_thread) {
+ if (new_thread != nullptr && new_thread->IsSuspendThread()) {
+ previous_thread->SetWasRunning(true);
+ }
previous_thread->SetContinuousOnSVC(false);
previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
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) {
return &SVC_Table_64[func_num];
}
-MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
-
void Call(Core::System& system, u32 immediate) {
- MICROPROFILE_SCOPE(Kernel_SVC);
+ system.ExitDynarmicProfile();
+ auto& kernel = system.Kernel();
+ kernel.EnterSVCProfile();
auto* thread = system.CurrentScheduler().GetCurrentThread();
thread->SetContinuousOnSVC(true);
@@ -2474,10 +2474,14 @@ void Call(Core::System& system, u32 immediate) {
LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate);
}
+ kernel.ExitSVCProfile();
+
if (!thread->IsContinuousOnSVC()) {
auto* host_context = thread->GetHostContext().get();
host_context->Rewind();
}
+
+ system.EnterDynarmicProfile();
}
} // 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:
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;
ThreadStatus GetStatus() const {
@@ -684,6 +700,8 @@ private:
bool will_be_terminated = false;
+ bool was_running = false;
+
std::string name;
};