Mercurial > dropbear
changeset 952:ef8d939de3dd
Fix clock_gettime handling
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 28 Jul 2014 22:48:48 +0800 |
parents | 9a48d8bcfeed |
children | 356a25a108a3 |
files | dbutil.c |
diffstat | 1 files changed, 34 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/dbutil.c Sun Jul 27 23:11:52 2014 +0800 +++ b/dbutil.c Mon Jul 28 22:48:48 2014 +0800 @@ -945,22 +945,45 @@ return c; } -time_t monotonic_now() { - #if defined(__linux__) && defined(SYS_clock_gettime) - /* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32. Probably cheaper. */ +/* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32 but took a while to +reach userspace include headers */ #ifndef CLOCK_MONOTONIC_COARSE #define CLOCK_MONOTONIC_COARSE 6 #endif - static clockid_t clock_source = CLOCK_MONOTONIC_COARSE; +static clockid_t get_linux_clock_source() { struct timespec ts; + if (syscall(SYS_clock_gettime, CLOCK_MONOTONIC_COARSE, &ts) == 0) { + return CLOCK_MONOTONIC_COARSE; + } + if (syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts) == 0) { + return CLOCK_MONOTONIC; + } + return -1; +} +#endif + +time_t monotonic_now() { +#if defined(__linux__) && defined(SYS_clock_gettime) + static clockid_t clock_source = -2; - if (syscall(SYS_clock_gettime, clock_source, &ts) == EINVAL) { - clock_source = CLOCK_MONOTONIC; - syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts); + if (clock_source == -2) { + /* First time, find out which one works. + -1 will fall back to time() */ + clock_source = get_linux_clock_source(); } - return ts.tv_sec; -#elif defined(HAVE_MACH_ABSOLUTE_TIME) + + if (clock_source >= 0) { + struct timespec ts; + if (syscall(SYS_clock_gettime, clock_source, &ts) != 0) { + /* Intermittent clock failures should not happen */ + dropbear_exit("Clock broke"); + } + return ts.tv_sec; + } +#endif /* linux clock_gettime */ + +#if defined(HAVE_MACH_ABSOLUTE_TIME) /* OS X, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */ static mach_timebase_info_data_t timebase_info; if (timebase_info.denom == 0) { @@ -968,10 +991,9 @@ } return mach_absolute_time() * timebase_info.numer / timebase_info.denom / 1e9; -#else +#endif /* osx mach_absolute_time */ + /* Fallback for everything else - this will sometimes go backwards */ return time(NULL); -#endif - }