#define _POSIX_C_SOURCE 200809L #include "timing.h" #include double timing_get_seconds(void) { struct timespec ts; // We enforce monotonic clock so system daylight saving updates don't break // delta logic clock_gettime(CLOCK_MONOTONIC, &ts); return (double)ts.tv_sec + (double)ts.tv_nsec / 1.0e9; } void timing_sleep_us(unsigned int microseconds) { struct timespec req; req.tv_sec = microseconds / 1000000; req.tv_nsec = (microseconds % 1000000) * 1000L; nanosleep(&req, NULL); } void timing_limit_fps(double frame_start_time, int target_fps) { if (target_fps <= 0) { return; } double target_frame_time = 1.0 / (double)target_fps; double elapsed = timing_get_seconds() - frame_start_time; double sleep_time = target_frame_time - elapsed; // Attempt dynamic throttle if (sleep_time > 0.0) { unsigned int sleep_us = (unsigned int)(sleep_time * 1.0e6); timing_sleep_us(sleep_us); } }