Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/kernel/kernel_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -11507,7 +11507,10 @@ static void kernel_thunk_dispatch(void)
fflush(stderr);
}

{
/* The two-second summary looks at the clock one call in 256: kernel
* calls come by the hundred thousand a second, and reading the time for
* each was a measurable share of a busy thread. */
if ((g_kernel_call_count & 255) == 0) {
static DWORD last_summary_tick = 0;
DWORD now = GetTickCount();
if (last_summary_tick == 0) last_summary_tick = now;
Expand Down
34 changes: 29 additions & 5 deletions src/platform/win32_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <sys/resource.h>
#include <limits.h>
#if defined(__APPLE__)
#include <mach/mach_time.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
#include <mach/mach.h>
Expand Down Expand Up @@ -1471,20 +1472,43 @@ VOID GetLocalTime(LPSYSTEMTIME st)
fill_systemtime(st, &tm, ts.tv_nsec);
}

ULONGLONG GetTickCount64(void)
/* The monotonic clock in nanoseconds, which QueryPerformanceCounter and
* GetTickCount are. On macOS clock_gettime(CLOCK_MONOTONIC) goes through
* gettimeofday and the boot time (17 ns a call on an M4), and the runtime
* reads the clock a great deal -- 7.5% of Constantine's main thread was
* those two -- so there it is mach_absolute_time (5 ns) and its timebase.
* It stops while the machine sleeps, which for a game is what is wanted. */
static inline uint64_t monotonic_ns(void)
{
#if defined(__APPLE__)
static uint32_t numer, denom;
uint64_t t = mach_absolute_time();
if (!denom) {
mach_timebase_info_data_t tb;
mach_timebase_info(&tb);
numer = tb.numer;
denom = tb.denom ? tb.denom : 1;
}
if (numer == denom)
return t;
return (uint64_t)(((unsigned __int128)t * numer) / denom);
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (ULONGLONG)ts.tv_sec * 1000ULL + (ULONGLONG)ts.tv_nsec / 1000000ULL;
return (uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec;
#endif
}

ULONGLONG GetTickCount64(void)
{
return (ULONGLONG)(monotonic_ns() / 1000000ULL);
}

DWORD GetTickCount(void) { return (DWORD)GetTickCount64(); }

BOOL QueryPerformanceCounter(PLARGE_INTEGER count)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
count->QuadPart = (LONGLONG)ts.tv_sec * 1000000000LL + ts.tv_nsec;
count->QuadPart = (LONGLONG)monotonic_ns();
return TRUE;
}

Expand Down
Loading