diff --git a/src/systime.h b/src/systime.h index 22ede456840..2e8fb454eee 100644 --- a/src/systime.h +++ b/src/systime.h @@ -79,6 +79,7 @@ enum { LO_TIME_BITS = 16 }; /* defined in timefns.c */ extern struct timeval make_timeval (struct timespec) ATTRIBUTE_CONST; +extern struct timespec monotonic_coarse_timespec (void); extern Lisp_Object make_lisp_time (struct timespec); extern Lisp_Object timespec_to_lisp (struct timespec); extern struct timespec list4_to_timespec (Lisp_Object, Lisp_Object, diff --git a/src/timefns.c b/src/timefns.c index 8cf424bbe7e..b4baeaaff82 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -138,6 +138,26 @@ make_timeval (struct timespec t) return tv; } +/* Return the current time with an epoch specific to this Emacs instance + (e.g., system boot). The clock should be unaffected by changes to + the system time, and should be cheap to access. Its resolution + should be appropriate for human time scales, e.g., better than 10 ms. + Make do with realtime if such a clock is not available. */ +struct timespec +monotonic_coarse_timespec (void) +{ + struct timespec ts; +#ifdef CLOCK_MONOTONIC_COARSE + if (clock_gettime (CLOCK_MONOTONIC_COARSE, &ts) == 0) + return ts; +#elif defined CLOCK_MONOTONIC + if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0) + return ts; +#endif + ts = current_timespec (); + return ts; +} + /* Yield A's UTC offset, or an unspecified value if unknown. */ static long int tm_gmtoff (struct tm *a) diff --git a/src/xterm.c b/src/xterm.c index d520ac1bdf5..e47a836713a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7067,22 +7067,15 @@ x_sync_get_monotonic_time (struct x_display_info *dpyinfo, return ckd_sub (&t, timestamp, dpyinfo->server_time_offset) ? 0 : t; } -# ifndef CLOCK_MONOTONIC -# define CLOCK_MONOTONIC CLOCK_REALTIME -# endif - /* Return the current monotonic time in the same format as a high-resolution server timestamp, or 0 if not available. */ static uint_fast64_t x_sync_current_monotonic_time (void) { - struct timespec time; + struct timespec time = monotonic_coarse_timespec (); uint_fast64_t t; - return (((clock_gettime (CLOCK_MONOTONIC, &time) != 0 - && (CLOCK_MONOTONIC == CLOCK_REALTIME - || clock_gettime (CLOCK_REALTIME, &time) != 0)) - || ckd_mul (&t, time.tv_sec, 1000000) + return ((ckd_mul (&t, time.tv_sec, 1000000) || ckd_add (&t, t, time.tv_nsec / 1000)) ? 0 : t); }