From: Lennart Poettering Date: Thu, 22 Jun 2017 18:52:23 +0000 (+0200) Subject: time-util: add new call usec_shift_clock() for converting times between clocks X-Git-Tag: v234~108^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1007ec60e664da03b7aea4803c643d991fcf6530;p=platform%2Fupstream%2Fsystemd.git time-util: add new call usec_shift_clock() for converting times between clocks We use that quite often, let's implement one clean version of it. --- diff --git a/src/basic/time-util.c b/src/basic/time-util.c index 51b0669..b0b1811 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -1351,3 +1351,22 @@ unsigned long usec_to_jiffies(usec_t u) { return DIV_ROUND_UP(u , USEC_PER_SEC / hz); } + +usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) { + usec_t a, b; + + if (x == USEC_INFINITY) + return USEC_INFINITY; + if (map_clock_id(from) == map_clock_id(to)) + return x; + + a = now(from); + b = now(to); + + if (x > a) + /* x lies in the future */ + return usec_add(b, usec_sub_unsigned(x, a)); + else + /* x lies in the past */ + return usec_sub_unsigned(b, usec_sub_unsigned(a, x)); +} diff --git a/src/basic/time-util.h b/src/basic/time-util.h index 8e2715c..414995e 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -145,6 +145,8 @@ bool clock_boottime_supported(void); bool clock_supported(clockid_t clock); clockid_t clock_boottime_or_monotonic(void); +usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to); + #define xstrftime(buf, fmt, tm) \ assert_message_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0, \ "xstrftime: " #buf "[] must be big enough") diff --git a/src/test/test-time.c b/src/test/test-time.c index 5523263..d9a6d61 100644 --- a/src/test/test-time.c +++ b/src/test/test-time.c @@ -331,6 +331,44 @@ static void test_dual_timestamp_deserialize(void) { assert_se(t.monotonic == 0); } +static void assert_similar(usec_t a, usec_t b) { + usec_t d; + + if (a > b) + d = a - b; + else + d = b - a; + + assert(d < 10*USEC_PER_SEC); +} + +static void test_usec_shift_clock(void) { + usec_t rt, mn, bt; + + rt = now(CLOCK_REALTIME); + mn = now(CLOCK_MONOTONIC); + bt = now(clock_boottime_or_monotonic()); + + assert_se(usec_shift_clock(USEC_INFINITY, CLOCK_REALTIME, CLOCK_MONOTONIC) == USEC_INFINITY); + + assert_similar(usec_shift_clock(rt + USEC_PER_HOUR, CLOCK_REALTIME, CLOCK_MONOTONIC), mn + USEC_PER_HOUR); + assert_similar(usec_shift_clock(rt + 2*USEC_PER_HOUR, CLOCK_REALTIME, clock_boottime_or_monotonic()), bt + 2*USEC_PER_HOUR); + assert_se(usec_shift_clock(rt + 3*USEC_PER_HOUR, CLOCK_REALTIME, CLOCK_REALTIME_ALARM) == rt + 3*USEC_PER_HOUR); + + assert_similar(usec_shift_clock(mn + 4*USEC_PER_HOUR, CLOCK_MONOTONIC, CLOCK_REALTIME_ALARM), rt + 4*USEC_PER_HOUR); + assert_similar(usec_shift_clock(mn + 5*USEC_PER_HOUR, CLOCK_MONOTONIC, clock_boottime_or_monotonic()), bt + 5*USEC_PER_HOUR); + assert_se(usec_shift_clock(mn + 6*USEC_PER_HOUR, CLOCK_MONOTONIC, CLOCK_MONOTONIC) == mn + 6*USEC_PER_HOUR); + + assert_similar(usec_shift_clock(bt + 7*USEC_PER_HOUR, clock_boottime_or_monotonic(), CLOCK_MONOTONIC), mn + 7*USEC_PER_HOUR); + assert_similar(usec_shift_clock(bt + 8*USEC_PER_HOUR, clock_boottime_or_monotonic(), CLOCK_REALTIME_ALARM), rt + 8*USEC_PER_HOUR); + assert_se(usec_shift_clock(bt + 9*USEC_PER_HOUR, clock_boottime_or_monotonic(), clock_boottime_or_monotonic()) == bt + 9*USEC_PER_HOUR); + + if (mn > USEC_PER_MINUTE) { + assert_similar(usec_shift_clock(rt - 30 * USEC_PER_SEC, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC), mn - 30 * USEC_PER_SEC); + assert_similar(usec_shift_clock(rt - 50 * USEC_PER_SEC, CLOCK_REALTIME, clock_boottime_or_monotonic()), bt - 50 * USEC_PER_SEC); + } +} + int main(int argc, char *argv[]) { uintmax_t x; @@ -348,6 +386,7 @@ int main(int argc, char *argv[]) { test_format_timestamp(); test_format_timestamp_utc(); test_dual_timestamp_deserialize(); + test_usec_shift_clock(); /* Ensure time_t is signed */ assert_cc((time_t) -1 < (time_t) 1);