// convert between unix epoch and clock_monotonic (ms since boot) static int64_t g_realtime_to_monotonic_offset_ms = 0; // In event_loop() at startup: static void init_realtime_monotonic_offset(void) { struct timespec monotonic_ts; struct timespec realtime_ts; clock_gettime(CLOCK_MONOTONIC, &monotonic_ts); clock_gettime(CLOCK_REALTIME, &realtime_ts); int64_t realtime_ms = realtime_ts.tv_sec * 1000LL + realtime_ts.tv_nsec / 1000000; int64_t monotonic_ms = monotonic_ts.tv_sec * 1000LL + monotonic_ts.tv_nsec / 1000000; g_realtime_to_monotonic_offset_ms = realtime_ms - monotonic_ms; } static int64_t epoch_to_monotonic_ms(int64_t epoch){ int64_t const epochms = epoch * 1000; int64_t const monotonic_ms = epochms - g_realtime_to_monotonic_offset_ms; assert(monotonic_ms >= 0); return monotonic_ms; }