Просмотр исходного кода

core_timing: Fix SingleCore cycle timer

Morph 3 лет назад
Родитель
Сommit
2e1e725443
4 измененных файлов с 31 добавлено и 43 удалено
  1. 20 16
      src/common/wall_clock.h
  2. 9 17
      src/core/core_timing.cpp
  3. 1 1
      src/core/core_timing.h
  4. 1 9
      src/core/hle/kernel/svc/svc_tick.cpp

+ 20 - 16
src/common/wall_clock.h

@@ -13,8 +13,9 @@ namespace Common {
 
 
 class WallClock {
 class WallClock {
 public:
 public:
-    static constexpr u64 CNTFRQ = 19'200'000;       // CNTPCT_EL0 Frequency = 19.2 MHz
-    static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz
+    static constexpr u64 CNTFRQ = 19'200'000;         // CNTPCT_EL0 Frequency = 19.2 MHz
+    static constexpr u64 GPUTickFreq = 614'400'000;   // GM20B GPU Tick Frequency = 614.4 MHz
+    static constexpr u64 CPUTickFreq = 1'020'000'000; // T210/4 A57 CPU Tick Frequency = 1020.0 MHz
 
 
     virtual ~WallClock() = default;
     virtual ~WallClock() = default;
 
 
@@ -46,28 +47,26 @@ public:
         return ns * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
         return ns * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
     }
     }
 
 
-    static inline u64 USToCNTPCT(u64 us) {
-        return us * UsToCNTPCTRatio::num / UsToCNTPCTRatio::den;
-    }
-
     static inline u64 NSToGPUTick(u64 ns) {
     static inline u64 NSToGPUTick(u64 ns) {
         return ns * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
         return ns * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
     }
     }
 
 
-    static inline u64 CNTPCTToNS(u64 cntpct) {
-        return cntpct * NsToCNTPCTRatio::den / NsToCNTPCTRatio::num;
+    // Cycle Timing
+
+    static inline u64 CPUTickToNS(u64 cpu_tick) {
+        return cpu_tick * CPUTickToNsRatio::num / CPUTickToNsRatio::den;
     }
     }
 
 
-    static inline u64 CNTPCTToUS(u64 cntpct) {
-        return cntpct * UsToCNTPCTRatio::den / UsToCNTPCTRatio::num;
+    static inline u64 CPUTickToUS(u64 cpu_tick) {
+        return cpu_tick * CPUTickToUsRatio::num / CPUTickToUsRatio::den;
     }
     }
 
 
-    static inline u64 GPUTickToNS(u64 gpu_tick) {
-        return gpu_tick * NsToGPUTickRatio::den / NsToGPUTickRatio::num;
+    static inline u64 CPUTickToCNTPCT(u64 cpu_tick) {
+        return cpu_tick * CPUTickToCNTPCTRatio::num / CPUTickToCNTPCTRatio::den;
     }
     }
 
 
-    static inline u64 CNTPCTToGPUTick(u64 cntpct) {
-        return cntpct * CNTPCTToGPUTickRatio::num / CNTPCTToGPUTickRatio::den;
+    static inline u64 CPUTickToGPUTick(u64 cpu_tick) {
+        return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den;
     }
     }
 
 
 protected:
 protected:
@@ -78,9 +77,14 @@ protected:
     using NsToUsRatio = std::ratio_divide<std::nano, std::micro>;
     using NsToUsRatio = std::ratio_divide<std::nano, std::micro>;
     using NsToMsRatio = std::ratio_divide<std::nano, std::milli>;
     using NsToMsRatio = std::ratio_divide<std::nano, std::milli>;
     using NsToCNTPCTRatio = std::ratio<CNTFRQ, std::nano::den>;
     using NsToCNTPCTRatio = std::ratio<CNTFRQ, std::nano::den>;
-    using UsToCNTPCTRatio = std::ratio<CNTFRQ, std::micro::den>;
     using NsToGPUTickRatio = std::ratio<GPUTickFreq, std::nano::den>;
     using NsToGPUTickRatio = std::ratio<GPUTickFreq, std::nano::den>;
-    using CNTPCTToGPUTickRatio = std::ratio<GPUTickFreq, CNTFRQ>;
+
+    // Cycle Timing
+
+    using CPUTickToNsRatio = std::ratio<std::nano::den, CPUTickFreq>;
+    using CPUTickToUsRatio = std::ratio<std::micro::den, CPUTickFreq>;
+    using CPUTickToCNTPCTRatio = std::ratio<CNTFRQ, CPUTickFreq>;
+    using CPUTickToGPUTickRatio = std::ratio<GPUTickFreq, CPUTickFreq>;
 };
 };
 
 
 std::unique_ptr<WallClock> CreateOptimalClock();
 std::unique_ptr<WallClock> CreateOptimalClock();

+ 9 - 17
src/core/core_timing.cpp

@@ -20,7 +20,7 @@
 
 
 namespace Core::Timing {
 namespace Core::Timing {
 
 
-constexpr s64 MAX_SLICE_LENGTH = 4000;
+constexpr s64 MAX_SLICE_LENGTH = 10000;
 
 
 std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callback) {
 std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callback) {
     return std::make_shared<EventType>(std::move(callback), std::move(name));
     return std::make_shared<EventType>(std::move(callback), std::move(name));
@@ -65,7 +65,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
     on_thread_init = std::move(on_thread_init_);
     on_thread_init = std::move(on_thread_init_);
     event_fifo_id = 0;
     event_fifo_id = 0;
     shutting_down = false;
     shutting_down = false;
-    ticks = 0;
+    cpu_ticks = 0;
     const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds)
     const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds)
         -> std::optional<std::chrono::nanoseconds> { return std::nullopt; };
         -> std::optional<std::chrono::nanoseconds> { return std::nullopt; };
     ev_lost = CreateEvent("_lost_event", empty_timed_callback);
     ev_lost = CreateEvent("_lost_event", empty_timed_callback);
@@ -170,20 +170,12 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
 }
 }
 
 
 void CoreTiming::AddTicks(u64 ticks_to_add) {
 void CoreTiming::AddTicks(u64 ticks_to_add) {
-    ticks += ticks_to_add;
-    downcount -= static_cast<s64>(ticks);
+    cpu_ticks += ticks_to_add;
+    downcount -= static_cast<s64>(cpu_ticks);
 }
 }
 
 
 void CoreTiming::Idle() {
 void CoreTiming::Idle() {
-    if (!event_queue.empty()) {
-        const u64 next_event_time = event_queue.front().time;
-        const u64 next_ticks = Common::WallClock::NSToCNTPCT(next_event_time) + 10U;
-        if (next_ticks > ticks) {
-            ticks = next_ticks;
-        }
-        return;
-    }
-    ticks += 1000U;
+    cpu_ticks += 1000U;
 }
 }
 
 
 void CoreTiming::ResetTicks() {
 void CoreTiming::ResetTicks() {
@@ -194,14 +186,14 @@ u64 CoreTiming::GetClockTicks() const {
     if (is_multicore) [[likely]] {
     if (is_multicore) [[likely]] {
         return clock->GetCNTPCT();
         return clock->GetCNTPCT();
     }
     }
-    return ticks;
+    return Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
 }
 }
 
 
 u64 CoreTiming::GetGPUTicks() const {
 u64 CoreTiming::GetGPUTicks() const {
     if (is_multicore) [[likely]] {
     if (is_multicore) [[likely]] {
         return clock->GetGPUTick();
         return clock->GetGPUTick();
     }
     }
-    return Common::WallClock::CNTPCTToGPUTick(ticks);
+    return Common::WallClock::CPUTickToGPUTick(cpu_ticks);
 }
 }
 
 
 std::optional<s64> CoreTiming::Advance() {
 std::optional<s64> CoreTiming::Advance() {
@@ -314,14 +306,14 @@ std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
     if (is_multicore) [[likely]] {
     if (is_multicore) [[likely]] {
         return clock->GetTimeNS();
         return clock->GetTimeNS();
     }
     }
-    return std::chrono::nanoseconds{Common::WallClock::CNTPCTToNS(ticks)};
+    return std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)};
 }
 }
 
 
 std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
 std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
     if (is_multicore) [[likely]] {
     if (is_multicore) [[likely]] {
         return clock->GetTimeUS();
         return clock->GetTimeUS();
     }
     }
-    return std::chrono::microseconds{Common::WallClock::CNTPCTToUS(ticks)};
+    return std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)};
 }
 }
 
 
 } // namespace Core::Timing
 } // namespace Core::Timing

+ 1 - 1
src/core/core_timing.h

@@ -167,7 +167,7 @@ private:
     s64 pause_end_time{};
     s64 pause_end_time{};
 
 
     /// Cycle timing
     /// Cycle timing
-    u64 ticks{};
+    u64 cpu_ticks{};
     s64 downcount{};
     s64 downcount{};
 };
 };
 
 

+ 1 - 9
src/core/hle/kernel/svc/svc_tick.cpp

@@ -12,16 +12,8 @@ namespace Kernel::Svc {
 int64_t GetSystemTick(Core::System& system) {
 int64_t GetSystemTick(Core::System& system) {
     LOG_TRACE(Kernel_SVC, "called");
     LOG_TRACE(Kernel_SVC, "called");
 
 
-    auto& core_timing = system.CoreTiming();
-
     // Returns the value of cntpct_el0 (https://switchbrew.org/wiki/SVC#svcGetSystemTick)
     // Returns the value of cntpct_el0 (https://switchbrew.org/wiki/SVC#svcGetSystemTick)
-    const u64 result{core_timing.GetClockTicks()};
-
-    if (!system.Kernel().IsMulticore()) {
-        core_timing.AddTicks(400U);
-    }
-
-    return static_cast<int64_t>(result);
+    return static_cast<int64_t>(system.CoreTiming().GetClockTicks());
 }
 }
 
 
 int64_t GetSystemTick64(Core::System& system) {
 int64_t GetSystemTick64(Core::System& system) {