From: Rusty Russell Date: Tue, 3 Jun 2014 10:39:04 +0000 (+0930) Subject: io failtest timer tools: fallout from time changes. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=daf9ee7d8e2b683ff05283beb1843611ad8c9e8a io failtest timer tools: fallout from time changes. Signed-off-by: Rusty Russell --- diff --git a/ccan/failtest/failtest.c b/ccan/failtest/failtest.c index fda2b344..ab8e19cd 100644 --- a/ccan/failtest/failtest.c +++ b/ccan/failtest/failtest.c @@ -91,7 +91,7 @@ static int control_fd = -1; /* If we're a child, this is the first call we did ourselves. */ static struct failtest_call *our_history_start = NULL; /* For printing runtime with --trace. */ -static struct timespec start; +static struct timeabs start; /* Set when failtest_hook returns FAIL_PROBE */ static bool probing = false; /* Table to track duplicates. */ @@ -761,13 +761,13 @@ static bool should_fail(struct failtest_call *call) if (child == 0) { traceindent++; if (tracef) { - struct timespec diff; + struct timerel diff; const char *p; char *failpath; struct failtest_call *c; c = tlist_tail(&history, list); - diff = time_sub(time_now(), start); + diff = time_between(time_now(), start); failpath = failpath_string(); p = strrchr(c->file, '/'); if (p) @@ -776,7 +776,7 @@ static bool should_fail(struct failtest_call *call) p = c->file; trace("%u->%u (%u.%02u): %s (%s:%u)\n", getppid(), getpid(), - (int)diff.tv_sec, (int)diff.tv_nsec / 10000000, + (int)diff.ts.tv_sec, (int)diff.ts.tv_nsec / 10000000, failpath, p, c->line); free(failpath); } diff --git a/ccan/io/backend.h b/ccan/io/backend.h index b6674025..b59b9fa3 100644 --- a/ccan/io/backend.h +++ b/ccan/io/backend.h @@ -92,7 +92,7 @@ bool add_duplex(struct io_conn *c); void del_listener(struct io_listener *l); void backend_plan_changed(struct io_conn *conn); void backend_wait_changed(const void *wait); -void backend_add_timeout(struct io_conn *conn, struct timespec ts); +void backend_add_timeout(struct io_conn *conn, struct timerel duration); void backend_del_timeout(struct io_conn *conn); void backend_del_conn(struct io_conn *conn); diff --git a/ccan/io/io.c b/ccan/io/io.c index 4c73b624..3f618249 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -198,7 +198,7 @@ struct io_conn *io_duplex_(struct io_conn *old, struct io_plan plan) return conn; } -bool io_timeout_(struct io_conn *conn, struct timespec ts, +bool io_timeout_(struct io_conn *conn, struct timerel t, struct io_plan (*cb)(struct io_conn *, void *), void *arg) { assert(cb); @@ -212,7 +212,7 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts, conn->timeout->next = cb; conn->timeout->next_arg = arg; - backend_add_timeout(conn, ts); + backend_add_timeout(conn, t); return true; } diff --git a/ccan/io/io.h b/ccan/io/io.h index 505c4c70..3bc1c1fa 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -391,7 +391,7 @@ struct io_plan io_wait_(const void *wait, /** * io_timeout - set timeout function if the callback doesn't complete. * @conn: the current connection. - * @ts: how long until the timeout should be called. + * @t: how long until the timeout should be called. * @cb: callback to call. * @arg: argument to @cb. * @@ -419,7 +419,7 @@ struct io_plan io_wait_(const void *wait, (fn), (arg), \ struct io_conn *), \ (arg)) -bool io_timeout_(struct io_conn *conn, struct timespec ts, +bool io_timeout_(struct io_conn *conn, struct timerel t, struct io_plan (*fn)(struct io_conn *, void *), void *arg); /** diff --git a/ccan/io/poll.c b/ccan/io/poll.c index 8ba376a5..2fd39f6b 100644 --- a/ccan/io/poll.c +++ b/ccan/io/poll.c @@ -285,12 +285,12 @@ static bool finish_conns(struct io_conn **ready) return false; } -void backend_add_timeout(struct io_conn *conn, struct timespec duration) +void backend_add_timeout(struct io_conn *conn, struct timerel duration) { if (!timeouts.base) timers_init(&timeouts, time_now()); timer_add(&timeouts, &conn->timeout->timer, - time_add(time_now(), duration)); + timeabs_add(time_now(), duration)); conn->timeout->conn = conn; } @@ -330,11 +330,11 @@ void *do_io_loop(struct io_conn **ready) while (!io_loop_return) { int i, r, timeout = INT_MAX; - struct timespec now; + struct timeabs now; bool some_timeouts = false; if (timeouts.base) { - struct timespec first; + struct timeabs first; struct list_head expired; struct io_timeout *t; @@ -353,7 +353,7 @@ void *do_io_loop(struct io_conn **ready) /* Now figure out how long to wait for the next one. */ if (timer_earliest(&timeouts, &first)) { - uint64_t f = time_to_msec(time_sub(first, now)); + uint64_t f = time_to_msec(time_between(first, now)); if (f < INT_MAX) timeout = f; } diff --git a/ccan/timer/_info b/ccan/timer/_info index cb6808b4..580b115c 100644 --- a/ccan/timer/_info +++ b/ccan/timer/_info @@ -37,14 +37,14 @@ * s = malloc(sizeof(*s)); * s->string = argv[1]; * timer_add(&timers, &s->timer, - * time_add(time_now(), - * time_from_msec(atol(argv[2])))); + * timeabs_add(time_now(), + * time_from_msec(atol(argv[2])))); * list_add_tail(&strings, &s->node); * argv += 2; * } * * while (!list_empty(&strings)) { - * struct timespec now = time_now(); + * struct timeabs now = time_now(); * list_for_each(&strings, s, node) * printf("%s", s->string); * timers_expire(&timers, now, &expired); diff --git a/ccan/timer/test/run-add.c b/ccan/timer/test/run-add.c index 6c5007c7..a7ea4f60 100644 --- a/ccan/timer/test/run-add.c +++ b/ccan/timer/test/run-add.c @@ -20,11 +20,12 @@ int main(void) struct timer t; uint64_t diff; unsigned int i; + struct timeabs epoch = { { 0, 0 } }; /* This is how many tests you plan to run */ plan_tests(2 + (18 + (MAX_ORD - 4) * 3) * (18 + (MAX_ORD - 4) * 3)); - timers_init(&timers, time_from_nsec(0)); + timers_init(&timers, epoch); ok1(timers_check(&timers, NULL)); for (i = 0; i < 4; i++) diff --git a/ccan/timer/test/run-ff.c b/ccan/timer/test/run-ff.c index c40e3b10..0f398d55 100644 --- a/ccan/timer/test/run-ff.c +++ b/ccan/timer/test/run-ff.c @@ -3,6 +3,12 @@ #include #include +static struct timeabs timeabs_from_usec(unsigned long long usec) +{ + struct timeabs epoch = { { 0, 0 } }; + return timeabs_add(epoch, time_from_usec(usec)); +} + int main(void) { struct timers timers; @@ -12,11 +18,11 @@ int main(void) /* This is how many tests you plan to run */ plan_tests(3); - timers_init(&timers, time_from_usec(1364726722653919ULL)); - timer_add(&timers, &t, time_from_usec(1364726722703919ULL)); - timers_expire(&timers, time_from_usec(1364726722653920ULL), &expired); + timers_init(&timers, timeabs_from_usec(1364726722653919ULL)); + timer_add(&timers, &t, timeabs_from_usec(1364726722703919ULL)); + timers_expire(&timers, timeabs_from_usec(1364726722653920ULL), &expired); ok1(list_empty(&expired)); - timers_expire(&timers, time_from_usec(1364726725454187ULL), &expired); + timers_expire(&timers, timeabs_from_usec(1364726725454187ULL), &expired); ok1(!list_empty(&expired)); ok1(list_top(&expired, struct timer, list) == &t); diff --git a/ccan/timer/test/run.c b/ccan/timer/test/run.c index 2946ba10..cebc99ce 100644 --- a/ccan/timer/test/run.c +++ b/ccan/timer/test/run.c @@ -3,34 +3,41 @@ #include #include +static struct timeabs timeabs_from_nsec(unsigned long long nsec) +{ + struct timeabs epoch = { { 0, 0 } }; + return timeabs_add(epoch, time_from_nsec(nsec)); +} + int main(void) { struct timers timers; struct timer t[64]; struct list_head expired; - struct timespec earliest; + struct timeabs earliest; uint64_t i; + struct timeabs epoch = { { 0, 0 } }; /* This is how many tests you plan to run */ plan_tests(488); - timers_init(&timers, time_from_nsec(0)); + timers_init(&timers, epoch); ok1(timers_check(&timers, NULL)); ok1(!timer_earliest(&timers, &earliest)); - timer_add(&timers, &t[0], time_from_nsec(1)); + timer_add(&timers, &t[0], timeabs_from_nsec(1)); ok1(timers_check(&timers, NULL)); ok1(timer_earliest(&timers, &earliest)); - ok1(time_eq(earliest, grains_to_time(t[0].time))); + ok1(timeabs_eq(earliest, grains_to_time(t[0].time))); timer_del(&timers, &t[0]); ok1(timers_check(&timers, NULL)); ok1(!timer_earliest(&timers, &earliest)); /* Check timer ordering. */ for (i = 0; i < 32; i++) { - timer_add(&timers, &t[i*2], time_from_nsec(1ULL << i)); + timer_add(&timers, &t[i*2], timeabs_from_nsec(1ULL << i)); ok1(timers_check(&timers, NULL)); - timer_add(&timers, &t[i*2+1], time_from_nsec((1ULL << i) + 1)); + timer_add(&timers, &t[i*2+1], timeabs_from_nsec((1ULL << i) + 1)); ok1(timers_check(&timers, NULL)); } @@ -52,9 +59,9 @@ int main(void) for (i = 0; i < 32; i++) { uint64_t exp = (uint64_t)TIMER_GRANULARITY << i; - timer_add(&timers, &t[i*2], time_from_nsec(exp)); + timer_add(&timers, &t[i*2], timeabs_from_nsec(exp)); ok1(timers_check(&timers, NULL)); - timer_add(&timers, &t[i*2+1], time_from_nsec(exp + 1)); + timer_add(&timers, &t[i*2+1], timeabs_from_nsec(exp + 1)); ok1(timers_check(&timers, NULL)); } diff --git a/ccan/timer/timer.c b/ccan/timer/timer.c index cf3bfd9d..c30c6227 100644 --- a/ccan/timer/timer.c +++ b/ccan/timer/timer.c @@ -12,23 +12,23 @@ struct timer_level { struct list_head list[PER_LEVEL]; }; -static uint64_t time_to_grains(struct timespec ts) +static uint64_t time_to_grains(struct timeabs t) { - return ts.tv_sec * ((uint64_t)1000000000 / TIMER_GRANULARITY) - + (ts.tv_nsec / TIMER_GRANULARITY); + return t.ts.tv_sec * ((uint64_t)1000000000 / TIMER_GRANULARITY) + + (t.ts.tv_nsec / TIMER_GRANULARITY); } -static struct timespec grains_to_time(uint64_t grains) +static struct timeabs grains_to_time(uint64_t grains) { - struct timespec ts; + struct timeabs t; - ts.tv_sec = grains / (1000000000 / TIMER_GRANULARITY); - ts.tv_nsec = (grains % (1000000000 / TIMER_GRANULARITY)) + t.ts.tv_sec = grains / (1000000000 / TIMER_GRANULARITY); + t.ts.tv_nsec = (grains % (1000000000 / TIMER_GRANULARITY)) * TIMER_GRANULARITY; - return ts; + return t; } -void timers_init(struct timers *timers, struct timespec start) +void timers_init(struct timers *timers, struct timeabs start) { unsigned int i; @@ -63,7 +63,7 @@ static void timer_add_raw(struct timers *timers, struct timer *t) list_add_tail(l, &t->list); } -void timer_add(struct timers *timers, struct timer *t, struct timespec when) +void timer_add(struct timers *timers, struct timer *t, struct timeabs when) { t->time = time_to_grains(when); @@ -203,7 +203,7 @@ static bool update_first(struct timers *timers) return true; } -bool timer_earliest(struct timers *timers, struct timespec *first) +bool timer_earliest(struct timers *timers, struct timeabs *first) { if (!update_first(timers)) return false; @@ -261,7 +261,7 @@ static void timer_fast_forward(struct timers *timers, uint64_t time) /* Fills list of expired timers. */ void timers_expire(struct timers *timers, - struct timespec expire, + struct timeabs expire, struct list_head *list) { uint64_t now = time_to_grains(expire); diff --git a/ccan/timer/timer.h b/ccan/timer/timer.h index d6e81e8c..79399cc4 100644 --- a/ccan/timer/timer.h +++ b/ccan/timer/timer.h @@ -31,7 +31,7 @@ struct timer; * * timers_init(&timeouts, time_now()); */ -void timers_init(struct timers *timers, struct timespec start); +void timers_init(struct timers *timers, struct timeabs start); /** * timers_cleanup - free allocations within timers struct. @@ -57,10 +57,9 @@ void timers_cleanup(struct timers *timers); * struct timer t; * * // Timeout in 100ms. - * timer_add(&timeouts, &t, time_add(time_now(), time_from_msec(100))); + * timer_add(&timeouts, &t, timeabs_add(time_now(), time_from_msec(100))); */ -void timer_add(struct timers *timers, struct timer *timer, - struct timespec when); +void timer_add(struct timers *timers, struct timer *timer, struct timeabs when); /** * timer_del - remove an unexpired timer. @@ -77,17 +76,17 @@ void timer_del(struct timers *timers, struct timer *timer); /** * timer_earliest - find out the first time when a timer will expire * @timers: the struct timers - * @first: the time, only set if there is a timer. + * @first: the expiry time, only set if there is a timer. * * This returns false, and doesn't alter @first if there are no * timers. Otherwise, it sets @first to the expiry time of the first * timer (rounded to TIMER_GRANULARITY nanoseconds), and returns true. * * Example: - * struct timespec next = { (time_t)-1ULL, -1UL }; + * struct timeabs next = { { (time_t)-1ULL, -1UL } }; * timer_earliest(&timeouts, &next); */ -bool timer_earliest(struct timers *timers, struct timespec *first); +bool timer_earliest(struct timers *timers, struct timeabs *first); /** * timers_expire - update timers structure and remove expired timers. @@ -114,7 +113,7 @@ bool timer_earliest(struct timers *timers, struct timespec *first); * printf("Timer expired!\n"); */ void timers_expire(struct timers *timers, - struct timespec expire, + struct timeabs expire, struct list_head *list); /** diff --git a/tools/ccanlint/async.c b/tools/ccanlint/async.c index f222e380..d867079d 100644 --- a/tools/ccanlint/async.c +++ b/tools/ccanlint/async.c @@ -68,7 +68,7 @@ static void run_more(void) signal(SIGALRM, killme); itim.it_interval.tv_sec = itim.it_interval.tv_usec = 0; - itim.it_value = timespec_to_timeval(time_from_msec(c->time_ms)); + itim.it_value = timespec_to_timeval(time_from_msec(c->time_ms).ts); setitimer(ITIMER_REAL, &itim, NULL); c->status = system(c->command); diff --git a/tools/tools.c b/tools/tools.c index f0a9ad46..b78702d0 100644 --- a/tools/tools.c +++ b/tools/tools.c @@ -39,7 +39,7 @@ char *run_with_timeout(const void *ctx, const char *cmd, int p[2]; struct rbuf in; int status, ms; - struct timespec start; + struct timeabs start; *ok = false; if (pipe(p) != 0) @@ -71,7 +71,7 @@ char *run_with_timeout(const void *ctx, const char *cmd, signal(SIGALRM, killme); itim.it_interval.tv_sec = itim.it_interval.tv_usec = 0; - itim.it_value = timespec_to_timeval(time_from_msec(*timeout_ms)); + itim.it_value = timespec_to_timeval(time_from_msec(*timeout_ms).ts); setitimer(ITIMER_REAL, &itim, NULL); status = system(cmd); @@ -90,7 +90,7 @@ char *run_with_timeout(const void *ctx, const char *cmd, if (waitpid(pid, &status, 0) != pid) err(1, "Failed to wait for child"); - ms = time_to_msec(time_sub(time_now(), start)); + ms = time_to_msec(time_between(time_now(), start)); if (ms > *timeout_ms) *timeout_ms = 0; else