mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-20 17:59:08 +02:00
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>
82 lines
2.3 KiB
C++
82 lines
2.3 KiB
C++
#pragma once
|
|
#include <cstdint>
|
|
|
|
void TimeInit();
|
|
void TimeShutdown(); // Not really necessary to call, just for completeness.
|
|
|
|
// Seconds.
|
|
double time_now_d();
|
|
|
|
// Raw time in nanoseconds.
|
|
// The only intended use is to match the timings from VK_GOOGLE_display_timing.
|
|
uint64_t time_now_raw();
|
|
|
|
// This is only interesting for Linux, in relation to VK_GOOGLE_display_timing.
|
|
double from_time_raw(uint64_t raw_time);
|
|
double from_time_raw_relative(uint64_t raw_time);
|
|
|
|
// Seconds, Unix UTC time
|
|
double time_now_unix_utc();
|
|
double time_to_unix_utc(double timeNowSeconds);
|
|
|
|
// Sleep for milliseconds. Does not necessarily have millisecond granularity, especially on Windows.
|
|
// Requires a "reason" since sleeping generally should be very sparingly used. This
|
|
// can be logged if desired to figure out where we're wasting time.
|
|
void sleep_ms(int ms, const char *reason);
|
|
// Sleep for microseconds. Does not necessarily have microsecond granularity, especially on Windows.
|
|
void sleep_us(int us, const char *reason);
|
|
// Precise sleep. Can consume a little bit of CPU on Windows at least.
|
|
void sleep_precise(double seconds, const char *reason);
|
|
|
|
// Random sleep, used for debugging.
|
|
void sleep_random(double minSeconds, double maxSeconds, const char *reason);
|
|
|
|
// Yield. Signals that this thread is busy-waiting but wants to allow other hyperthreads to run.
|
|
void yield();
|
|
|
|
void GetCurrentTimeFormatted(char formattedTime[13]);
|
|
|
|
// Most accurate timer possible - no extra double conversions. Only for spans.
|
|
class Instant {
|
|
public:
|
|
Instant();
|
|
static Instant Now() {
|
|
return Instant();
|
|
}
|
|
double ElapsedSeconds() const;
|
|
double ElapsedMs() const { return ElapsedSeconds() * 1000.0; }
|
|
int64_t ElapsedNanos() const;
|
|
private:
|
|
// Windows: raw QPC ticks. Everything else: nanoseconds, from time_now_raw().
|
|
uint64_t nativeStart_;
|
|
};
|
|
|
|
class TimeCollector {
|
|
public:
|
|
TimeCollector(double *target, bool enable) : target_(enable ? target : nullptr) {
|
|
if (enable)
|
|
startTime_ = time_now_d();
|
|
}
|
|
~TimeCollector() {
|
|
if (target_) {
|
|
*target_ += time_now_d() - startTime_;
|
|
}
|
|
}
|
|
private:
|
|
double startTime_;
|
|
double *target_;
|
|
};
|
|
|
|
class LogScopeIfSlowMs {
|
|
public:
|
|
LogScopeIfSlowMs(const char *title, int limitMs) {
|
|
title_ = title;
|
|
endTime_ = time_now_d() + 0.001 * limitMs;
|
|
}
|
|
~LogScopeIfSlowMs();
|
|
|
|
private:
|
|
const char *title_;
|
|
double endTime_;
|
|
};
|