summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Morph2023-04-23 00:01:08 -0400
committerGravatar Morph2023-06-07 21:44:42 -0400
commit8e56a84566036cfff0aa5c3d80ae1b051d2bd0bf (patch)
tree2bb7be86aafe9986811758b508a7581d2efe8ac4 /src/core
parentnvnflinger: Acquire lock prior to signaling the vsync variable (diff)
downloadyuzu-8e56a84566036cfff0aa5c3d80ae1b051d2bd0bf.tar.gz
yuzu-8e56a84566036cfff0aa5c3d80ae1b051d2bd0bf.tar.xz
yuzu-8e56a84566036cfff0aa5c3d80ae1b051d2bd0bf.zip
core_timing: Use CNTPCT as the guest CPU tick
Previously, we were mixing the raw CPU frequency and CNTFRQ. The raw CPU frequency (1020 MHz) should've never been used as CNTPCT (whose frequency is CNTFRQ) is the only counter available.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/core_timing.cpp35
-rw-r--r--src/core/core_timing.h11
-rw-r--r--src/core/core_timing_util.h58
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp5
-rw-r--r--src/core/hle/kernel/svc/svc_info.cpp4
-rw-r--r--src/core/hle/service/hid/hidbus.cpp1
7 files changed, 15 insertions, 100 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 99602699a..3df4094a7 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -16,7 +16,6 @@ add_library(core STATIC
16 core.h 16 core.h
17 core_timing.cpp 17 core_timing.cpp
18 core_timing.h 18 core_timing.h
19 core_timing_util.h
20 cpu_manager.cpp 19 cpu_manager.cpp
21 cpu_manager.h 20 cpu_manager.h
22 crypto/aes_util.cpp 21 crypto/aes_util.cpp
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 4f2692b05..9a1d5a69a 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -16,7 +16,6 @@
16 16
17#include "common/microprofile.h" 17#include "common/microprofile.h"
18#include "core/core_timing.h" 18#include "core/core_timing.h"
19#include "core/core_timing_util.h"
20#include "core/hardware_properties.h" 19#include "core/hardware_properties.h"
21 20
22namespace Core::Timing { 21namespace Core::Timing {
@@ -45,9 +44,7 @@ struct CoreTiming::Event {
45 } 44 }
46}; 45};
47 46
48CoreTiming::CoreTiming() 47CoreTiming::CoreTiming() : clock{Common::CreateOptimalClock()} {}
49 : cpu_clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)},
50 event_clock{Common::CreateStandardWallClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
51 48
52CoreTiming::~CoreTiming() { 49CoreTiming::~CoreTiming() {
53 Reset(); 50 Reset();
@@ -180,7 +177,7 @@ void CoreTiming::AddTicks(u64 ticks_to_add) {
180void CoreTiming::Idle() { 177void CoreTiming::Idle() {
181 if (!event_queue.empty()) { 178 if (!event_queue.empty()) {
182 const u64 next_event_time = event_queue.front().time; 179 const u64 next_event_time = event_queue.front().time;
183 const u64 next_ticks = nsToCycles(std::chrono::nanoseconds(next_event_time)) + 10U; 180 const u64 next_ticks = Common::WallClock::NSToCNTPCT(next_event_time) + 10U;
184 if (next_ticks > ticks) { 181 if (next_ticks > ticks) {
185 ticks = next_ticks; 182 ticks = next_ticks;
186 } 183 }
@@ -193,18 +190,11 @@ void CoreTiming::ResetTicks() {
193 downcount = MAX_SLICE_LENGTH; 190 downcount = MAX_SLICE_LENGTH;
194} 191}
195 192
196u64 CoreTiming::GetCPUTicks() const {
197 if (is_multicore) [[likely]] {
198 return cpu_clock->GetCPUCycles();
199 }
200 return ticks;
201}
202
203u64 CoreTiming::GetClockTicks() const { 193u64 CoreTiming::GetClockTicks() const {
204 if (is_multicore) [[likely]] { 194 if (is_multicore) [[likely]] {
205 return cpu_clock->GetClockCycles(); 195 return clock->GetCNTPCT();
206 } 196 }
207 return CpuCyclesToClockCycles(ticks); 197 return ticks;
208} 198}
209 199
210std::optional<s64> CoreTiming::Advance() { 200std::optional<s64> CoreTiming::Advance() {
@@ -297,9 +287,7 @@ void CoreTiming::ThreadLoop() {
297 } 287 }
298 288
299 paused_set = true; 289 paused_set = true;
300 event_clock->Pause(true);
301 pause_event.Wait(); 290 pause_event.Wait();
302 event_clock->Pause(false);
303 } 291 }
304} 292}
305 293
@@ -315,25 +303,18 @@ void CoreTiming::Reset() {
315 has_started = false; 303 has_started = false;
316} 304}
317 305
318std::chrono::nanoseconds CoreTiming::GetCPUTimeNs() const {
319 if (is_multicore) [[likely]] {
320 return cpu_clock->GetTimeNS();
321 }
322 return CyclesToNs(ticks);
323}
324
325std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { 306std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
326 if (is_multicore) [[likely]] { 307 if (is_multicore) [[likely]] {
327 return event_clock->GetTimeNS(); 308 return clock->GetTimeNS();
328 } 309 }
329 return CyclesToNs(ticks); 310 return std::chrono::nanoseconds{Common::WallClock::CNTPCTToNS(ticks)};
330} 311}
331 312
332std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { 313std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
333 if (is_multicore) [[likely]] { 314 if (is_multicore) [[likely]] {
334 return event_clock->GetTimeUS(); 315 return clock->GetTimeUS();
335 } 316 }
336 return CyclesToUs(ticks); 317 return std::chrono::microseconds{Common::WallClock::CNTPCTToUS(ticks)};
337} 318}
338 319
339} // namespace Core::Timing 320} // namespace Core::Timing
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index e7c4a949f..fdacdd94a 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -116,15 +116,9 @@ public:
116 return downcount; 116 return downcount;
117 } 117 }
118 118
119 /// Returns current time in emulated CPU cycles 119 /// Returns the current CNTPCT tick value.
120 u64 GetCPUTicks() const;
121
122 /// Returns current time in emulated in Clock cycles
123 u64 GetClockTicks() const; 120 u64 GetClockTicks() const;
124 121
125 /// Returns current time in nanoseconds.
126 std::chrono::nanoseconds GetCPUTimeNs() const;
127
128 /// Returns current time in microseconds. 122 /// Returns current time in microseconds.
129 std::chrono::microseconds GetGlobalTimeUs() const; 123 std::chrono::microseconds GetGlobalTimeUs() const;
130 124
@@ -142,8 +136,7 @@ private:
142 136
143 void Reset(); 137 void Reset();
144 138
145 std::unique_ptr<Common::WallClock> cpu_clock; 139 std::unique_ptr<Common::WallClock> clock;
146 std::unique_ptr<Common::WallClock> event_clock;
147 140
148 s64 global_timer = 0; 141 s64 global_timer = 0;
149 142
diff --git a/src/core/core_timing_util.h b/src/core/core_timing_util.h
deleted file mode 100644
index fe5aaefc7..000000000
--- a/src/core/core_timing_util.h
+++ /dev/null
@@ -1,58 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <chrono>
7
8#include "common/common_types.h"
9#include "core/hardware_properties.h"
10
11namespace Core::Timing {
12
13namespace detail {
14constexpr u64 CNTFREQ_ADJUSTED = Hardware::CNTFREQ / 1000;
15constexpr u64 BASE_CLOCK_RATE_ADJUSTED = Hardware::BASE_CLOCK_RATE / 1000;
16} // namespace detail
17
18[[nodiscard]] constexpr s64 msToCycles(std::chrono::milliseconds ms) {
19 return ms.count() * detail::BASE_CLOCK_RATE_ADJUSTED;
20}
21
22[[nodiscard]] constexpr s64 usToCycles(std::chrono::microseconds us) {
23 return us.count() * detail::BASE_CLOCK_RATE_ADJUSTED / 1000;
24}
25
26[[nodiscard]] constexpr s64 nsToCycles(std::chrono::nanoseconds ns) {
27 return ns.count() * detail::BASE_CLOCK_RATE_ADJUSTED / 1000000;
28}
29
30[[nodiscard]] constexpr u64 msToClockCycles(std::chrono::milliseconds ms) {
31 return static_cast<u64>(ms.count()) * detail::CNTFREQ_ADJUSTED;
32}
33
34[[nodiscard]] constexpr u64 usToClockCycles(std::chrono::microseconds us) {
35 return us.count() * detail::CNTFREQ_ADJUSTED / 1000;
36}
37
38[[nodiscard]] constexpr u64 nsToClockCycles(std::chrono::nanoseconds ns) {
39 return ns.count() * detail::CNTFREQ_ADJUSTED / 1000000;
40}
41
42[[nodiscard]] constexpr u64 CpuCyclesToClockCycles(u64 ticks) {
43 return ticks * detail::CNTFREQ_ADJUSTED / detail::BASE_CLOCK_RATE_ADJUSTED;
44}
45
46[[nodiscard]] constexpr std::chrono::milliseconds CyclesToMs(s64 cycles) {
47 return std::chrono::milliseconds(cycles / detail::BASE_CLOCK_RATE_ADJUSTED);
48}
49
50[[nodiscard]] constexpr std::chrono::nanoseconds CyclesToNs(s64 cycles) {
51 return std::chrono::nanoseconds(cycles * 1000000 / detail::BASE_CLOCK_RATE_ADJUSTED);
52}
53
54[[nodiscard]] constexpr std::chrono::microseconds CyclesToUs(s64 cycles) {
55 return std::chrono::microseconds(cycles * 1000 / detail::BASE_CLOCK_RATE_ADJUSTED);
56}
57
58} // namespace Core::Timing
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index faa12b4f0..75ce5a23c 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -184,7 +184,8 @@ u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) {
184 prev_highest_thread != highest_thread) [[likely]] { 184 prev_highest_thread != highest_thread) [[likely]] {
185 if (prev_highest_thread != nullptr) [[likely]] { 185 if (prev_highest_thread != nullptr) [[likely]] {
186 IncrementScheduledCount(prev_highest_thread); 186 IncrementScheduledCount(prev_highest_thread);
187 prev_highest_thread->SetLastScheduledTick(m_kernel.System().CoreTiming().GetCPUTicks()); 187 prev_highest_thread->SetLastScheduledTick(
188 m_kernel.System().CoreTiming().GetClockTicks());
188 } 189 }
189 if (m_state.should_count_idle) { 190 if (m_state.should_count_idle) {
190 if (highest_thread != nullptr) [[likely]] { 191 if (highest_thread != nullptr) [[likely]] {
@@ -351,7 +352,7 @@ void KScheduler::SwitchThread(KThread* next_thread) {
351 352
352 // Update the CPU time tracking variables. 353 // Update the CPU time tracking variables.
353 const s64 prev_tick = m_last_context_switch_time; 354 const s64 prev_tick = m_last_context_switch_time;
354 const s64 cur_tick = m_kernel.System().CoreTiming().GetCPUTicks(); 355 const s64 cur_tick = m_kernel.System().CoreTiming().GetClockTicks();
355 const s64 tick_diff = cur_tick - prev_tick; 356 const s64 tick_diff = cur_tick - prev_tick;
356 cur_thread->AddCpuTime(m_core_id, tick_diff); 357 cur_thread->AddCpuTime(m_core_id, tick_diff);
357 if (cur_process != nullptr) { 358 if (cur_process != nullptr) {
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index 2b2c878b5..445cdd87b 100644
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -199,9 +199,9 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
199 if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) { 199 if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) {
200 const u64 thread_ticks = current_thread->GetCpuTime(); 200 const u64 thread_ticks = current_thread->GetCpuTime();
201 201
202 out_ticks = thread_ticks + (core_timing.GetCPUTicks() - prev_ctx_ticks); 202 out_ticks = thread_ticks + (core_timing.GetClockTicks() - prev_ctx_ticks);
203 } else if (same_thread && info_sub_id == system.Kernel().CurrentPhysicalCoreIndex()) { 203 } else if (same_thread && info_sub_id == system.Kernel().CurrentPhysicalCoreIndex()) {
204 out_ticks = core_timing.GetCPUTicks() - prev_ctx_ticks; 204 out_ticks = core_timing.GetClockTicks() - prev_ctx_ticks;
205 } 205 }
206 206
207 *result = out_ticks; 207 *result = out_ticks;
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index 5604a6fda..80aac221b 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -5,7 +5,6 @@
5#include "common/settings.h" 5#include "common/settings.h"
6#include "core/core.h" 6#include "core/core.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/core_timing_util.h"
9#include "core/hid/hid_types.h" 8#include "core/hid/hid_types.h"
10#include "core/hle/kernel/k_event.h" 9#include "core/hle/kernel/k_event.h"
11#include "core/hle/kernel/k_readable_event.h" 10#include "core/hle/kernel/k_readable_event.h"