From: Bruno Haible Date: Tue, 8 Aug 2023 19:28:46 +0000 (+0200) Subject: readutmp: Get the boot time with higher precision. X-Git-Tag: v1.0~950 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=4b2608934b924f5aafd3ad15444595450298c589;p=gnulib.git readutmp: Get the boot time with higher precision. Suggested by Thorsten Kukuk in . * lib/readutmp.c (get_boot_time_uncached): Try clock_gettime first. --- diff --git a/ChangeLog b/ChangeLog index 1697d8a3b9..62e281fa97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-08-08 Bruno Haible + + readutmp: Get the boot time with higher precision. + Suggested by Thorsten Kukuk in + . + * lib/readutmp.c (get_boot_time_uncached): Try clock_gettime first. + 2023-08-08 Bruno Haible readutmp: Add comment about multithread-safety. diff --git a/lib/readutmp.c b/lib/readutmp.c index 7ef5bfe84c..f7e43eb4a6 100644 --- a/lib/readutmp.c +++ b/lib/readutmp.c @@ -284,6 +284,31 @@ finish_utmp (struct utmp_alloc a) static struct timespec get_boot_time_uncached (void) { + /* The clock_gettime facility returns the uptime with a resolution of 1 µsec. + It is available with glibc >= 2.14. In glibc < 2.17 it required linking + with librt. */ +# if __GLIBC__ + (__GLIBC_MINOR__ >= 17) > 2 + struct timespec up; + if (clock_gettime (CLOCK_BOOTTIME, &up) >= 0) + { + struct timespec result; + /* equivalent to: + if (clock_gettime (CLOCK_REALTIME, &result) >= 0) + */ + if (timespec_get (&result, TIME_UTC) >= 0) + { + if (result.tv_nsec < up.tv_nsec) + { + result.tv_nsec += 1000000000; + result.tv_sec -= 1; + } + result.tv_sec -= up.tv_sec; + result.tv_nsec -= up.tv_nsec; + return result; + } + } +# endif + /* /proc/uptime contains the uptime with a resolution of 0.01 sec. */ FILE *fp = fopen ("/proc/uptime", "re"); if (fp != NULL)