- 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>
The fallback (Switch, BSDs, anything not Windows/Linux/Android/Apple) mixed
clocks: time_now_d() read the wall clock with gettimeofday, time_now_raw()
and Instant a monotonic one, from_time_raw() didn't subtract the start time,
and time_to_unix_utc() added the timestamp to the current time instead of
the start time.
Now every non-Windows platform shares the same code, built on time_now_raw()
and time_now_unix_utc(). Those two use clock_gettime where we know it's there
and std::chrono's steady_clock/system_clock elsewhere. Instant stores a
single nanosecond timestamp, and time_to_unix_utc() (which was missing on
Linux/Android/Apple) is start time plus timestamp, like on Windows.
The time origin is now set in TimeInit() rather than lazily on the first
time_now_d(), which raced between threads. iOS never called TimeInit(), so
it does now.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This branch is live on the Switch and the BSDs - ppsspp_config.h only maps LINUX to
Android and Linux - and three of its functions didn't do what their callers assume.
time_now_raw() is documented and used as nanoseconds, and from_time_raw() scales it
by 1/nanos, but this built a double of *seconds* and returned it through the uint64_t
return type: the fraction was truncated away and the result was off by a factor of a
billion. Return real monotonic nanoseconds, like every other platform branch.
time_now_unix_utc() just forwarded to time_now_raw(), which is now explicitly a
monotonic clock with no relation to the epoch (and before this, was seconds truncated
to a whole number). Read the wall clock.
Instant took gettimeofday's tv_usec into nsecs_ and stored tv_sec as the start, while
ElapsedNanos() subtracts those from clock_gettime(CLOCK_MONOTONIC) - so it mixed two
different clocks *and* two different units, then applied a microsecond borrow to a
nanosecond difference. Elapsed times were nonsense and could come out negative.
sleep_ms() should generally be avoided when possible. This can be used to try
to track down unnecessary sleeps by adding some logging.
This commit on its own doesn't actually add any logging.
* Add yield() function to tell the CPU that we're busy-waiting (rare)
Use it only for the busy-wait in lag sync, which only happens in
Windows.
* Buildfix attempt