Common: Use CLOCK_UPTIME_RAW for the monotonic clock on Apple platforms

- Fixes #16823

CLOCK_UPTIME_RAW is mach_absolute_time() in nanoseconds (the same value, not
just the same rate). That's the clock MoltenVK reports VK_GOOGLE_display_timing
present times in, which time_now_raw() is meant to match. Apple's
CLOCK_MONOTONIC counts time asleep, unlike Linux's, so on a Mac that had
slept since boot, from_time_raw() of a present time was off by all of it.

It's also cheaper to read: ~19ns vs ~30ns on M1. mach_absolute_time() itself
is ~8ns, but returns ticks, and the timebase on Apple Silicon is 125/3.

Timing risk: time_now_d() no longer advances while the machine sleeps, so a
sleep/wake shows up as a small delta rather than a huge one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-19 14:17:52 +02:00
1 parent 79ccfa8fc7
commit 19b25a2e42
1 file changed
+7 -2
+7 -2
View File
@@ -147,9 +147,14 @@ int64_t Instant::ElapsedNanos() const {
#else
// Monotonic, in nanoseconds. On Linux and Android this is the clock VK_GOOGLE_display_timing reports in.
// Monotonic, in nanoseconds, and the clock VK_GOOGLE_display_timing reports in.
uint64_t time_now_raw() {
#if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(LINUX) || PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
#if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
// mach_absolute_time() in nanoseconds, which is what MoltenVK reports present times in. Apple's
// CLOCK_MONOTONIC keeps counting during sleep (unlike Linux's), so it drifts away from those,
// and is slower to read (~30ns vs ~19ns on M1).
return clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
#elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(LINUX)
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
return tp.tv_sec * 1000000000ULL + tp.tv_nsec;