diff options
author | Chris Hall (GMCH) <chris.hall@highwayman.com> | 2009-12-06 23:44:14 +0000 |
---|---|---|
committer | Chris Hall (GMCH) <chris.hall@highwayman.com> | 2009-12-06 23:44:14 +0000 |
commit | f3058d927bb083124519ea0a315f646bfbe52cb1 (patch) | |
tree | 1cb348bfffe271e14714b9ddb61eb9047bef65aa | |
parent | 20b6b088dd8864472dc03b1aaabfbb33d9b7ad47 (diff) | |
download | quagga-f3058d927bb083124519ea0a315f646bfbe52cb1.tar.bz2 quagga-f3058d927bb083124519ea0a315f646bfbe52cb1.tar.xz |
Updates to lib/qtime.c & .h
Added conversion routines for CLOCK_REALTIME/timeofday to/from
monotonic clock -- so can set timers to actual time, if required.
Added confirms and tidied up documentation.
-rw-r--r-- | lib/qtime.c | 14 | ||||
-rw-r--r-- | lib/qtime.h | 64 |
2 files changed, 66 insertions, 12 deletions
diff --git a/lib/qtime.c b/lib/qtime.c index cdcf09f9..3e1e8269 100644 --- a/lib/qtime.c +++ b/lib/qtime.c @@ -47,7 +47,7 @@ * * The qtime_t value is in nano-seconds. * - * The result from times() is in units of sysconf(_SC_CLK_TCK). + * The result from times() is in units of sysconf(_SC_CLK_TCK) ticks per second. * * NB: it is assumed that qt_craft_monotonic will be called often enough to * ensure that it is not fooled by the clock wrapping round. @@ -61,7 +61,7 @@ * So this should be a safe assumption -- particularly as 60, 100, 250 and * 1000 ticks per second appear to be the popular options. * - * For safety, this asserts that the value is <= 1,000,000. + * For safety, this asserts that sysconf(_SC_CLK_TCK) <= 1,000,000. */ #ifdef GNU_LINUX @@ -89,12 +89,12 @@ qt_craft_monotonic(void) { /* clock either to jump or to get stuck ! */ #ifdef TIMES_TAKES_NULL - this_times_sample = times(NULL) ; /* assume this saves effort ! */ + this_times_sample = times(NULL) ; /* assume this saves effort ! */ #else this_times_sample = times(&dummy) ; #endif - if (this_times_sample == (clock_t)-1) + if (this_times_sample == (uint64_t)-1) /* deal with theoretical error */ { errno = 0 ; this_times_sample = times(&dummy) ; @@ -102,7 +102,10 @@ qt_craft_monotonic(void) { zabort_errno("times() failed") ; } ; + /* Advance the monotonic clock in sysconf(_SC_CLK_TCK) units. */ + monotonic += (this_times_sample - last_times_sample) ; + /* Set up times_scale_q & times_scale_q if not yet done */ if (times_clk_tcks == 0) /* Is zero until it's initialized */ { lldiv_t qr ; @@ -118,8 +121,7 @@ qt_craft_monotonic(void) { last_times_sample = this_times_sample ; } ; - monotonic += (this_times_sample - last_times_sample) ; - + /* Scale to qtime_t units. */ if (times_scale_r == 0) return monotonic * times_scale_q ; else diff --git a/lib/qtime.h b/lib/qtime.h index 24c3eb8e..4cfdd1fb 100644 --- a/lib/qtime.h +++ b/lib/qtime.h @@ -88,22 +88,33 @@ qtime2timeval(struct timeval* p_tv, qtime_t qt) ; * * Monotonic Clock * * Using clock_gettime(CLOCK_MONOTONIC, &ts) if it is available, otherwise - * a manufactured equivalent using times(). + * a manufactured equivalent using times() -- see qt_craft_monotonic(). */ Inline qtime_t -qt_get_timeofday(void) ; /* gettimeofday(&tv, NULL) */ - -Inline qtime_t qt_get_realtime(void) ; /* clock_gettime(CLOCK_REALTIME, &ts) */ Inline qtime_t qt_get_monotonic(void) ; /* clock_gettime(CLOCK_MONOTONIC, &ts */ /* OR equivalent using times() */ +Inline qtime_t /* monotonic time from CLOCK_REALTIME */ +qt_realtime2monotonic(qtime_t realtime) ; +Inline qtime_t /* CLOCK_REALTIME from monotonic time */ +qt_monotonic2realtime(qtime_t monotonic) ; + /* Function to manufacture a monotonic clock. */ extern qtime_t qt_craft_monotonic(void) ; +/* These are provided just in case gettimeofday() != CLOCK_REALTIME */ +Inline qtime_t +qt_get_timeofday(void) ; /* gettimeofday(&tv, NULL) */ + +Inline qtime_t /* monotonic time from timeofday */ +qt_timeofday2monotonic(qtime_t timeofday) ; +Inline qtime_t /* timeofday from monotonic time */ +qt_monotonic2timeofday(qtime_t monotonic) ; + /*============================================================================== * Inline conversion functions */ @@ -115,7 +126,8 @@ extern qtime_t qt_craft_monotonic(void) ; Inline qtime_t timespec2qtime(struct timespec* p_ts) { - return ((qtime_t)(p_ts->tv_sec) * QTIME_SECOND) + p_ts->tv_nsec ; + return QTIME(p_ts->tv_sec) + p_ts->tv_nsec ; + confirm(QTIME_SECOND == TIMESPEC_SECOND) ; } ; /* Convert timeval to qtime_t @@ -125,7 +137,8 @@ timespec2qtime(struct timespec* p_ts) Inline qtime_t timeval2qtime(struct timeval* p_tv) { - return ((qtime_t)(p_tv->tv_sec) * QTIME_SECOND) + (p_tv->tv_usec * 1000) ; + return QTIME(p_tv->tv_sec) + (p_tv->tv_usec * 1000) ; + confirm(QTIME_SECOND == TIMEVAL_SECOND * 1000) ; } ; /* Convert qtime_t to timespec @@ -136,8 +149,11 @@ Inline struct timespec* qtime2timespec(struct timespec* p_ts, qtime_t qt) { lldiv_t imd = lldiv(qt, QTIME_SECOND) ; + confirm(sizeof(long long) >= sizeof(qtime_t)) ; + p_ts->tv_sec = imd.quot ; p_ts->tv_nsec = imd.rem ; + confirm(TIMESPEC_SECOND == QTIME_SECOND) ; return p_ts ; } ; @@ -150,8 +166,11 @@ Inline struct timeval* qtime2timeval(struct timeval* p_tv, qtime_t qt) { lldiv_t imd = lldiv(qt, QTIME_SECOND) ; + confirm(sizeof(long long) >= sizeof(qtime_t)) ; + p_tv->tv_sec = imd.quot ; p_tv->tv_usec = imd.rem / 1000 ; + confirm(TIMEVAL_SECOND * 1000 == QTIME_SECOND) ; return p_tv ; } ; @@ -211,4 +230,37 @@ qt_get_monotonic(void) #endif } ; +/*============================================================================== + * Conversion between realtime/timeofday and monotonic + * + */ + +/* Convert a CLOCK_REALTIME time to our local monotonic time. */ +Inline qtime_t +qt_realtime2monotonic(qtime_t realtime) +{ + return qt_get_monotonic() + (realtime - qt_get_realtime()) ; +} ; + +/* Convert a local monotonic time to CLOCK_REALTIME time. */ +Inline qtime_t +qt_monotonic2realtime(qtime_t monotonic) +{ + return qt_get_realtime() + (monotonic - qt_get_monotonic()) ; +} ; + +/* Convert a gettimeofday() time to our local monotonic time. */ +Inline qtime_t +qt_timeofday2monotonic(qtime_t timeofday) +{ + return qt_get_monotonic() + (timeofday - qt_get_timeofday()) ; +} ; + +/* Convert a local monotonic time to gettimeofday() time. */ +Inline qtime_t +qt_monotonic2timeofday(qtime_t monotonic) +{ + return qt_get_timeofday() + (monotonic - qt_get_monotonic()) ; +} ; + #endif /* _ZEBRA_QTIME_H */ |