diff options
author | Ben Pfaff <blp@nicira.com> | 2011-12-07 13:15:54 -0800 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2011-12-19 14:53:54 -0800 |
commit | 6197af6e4b9890f43380e0a0159886ba3275c75c (patch) | |
tree | a092117d738f288dd9a64f60a8f10878c38f4504 | |
parent | cee03df4f53a9629f1f18b6c9948362f55a3ae27 (diff) | |
download | openvswitch-6197af6e4b9890f43380e0a0159886ba3275c75c.tar.gz |
timeval: Add ability to fast-forward time, for unit testing.
Signed-off-by: Ben Pfaff <blp@nicira.com>
-rw-r--r-- | lib/dummy.h | 3 | ||||
-rw-r--r-- | lib/timeval.c | 54 |
2 files changed, 56 insertions, 1 deletions
diff --git a/lib/dummy.h b/lib/dummy.h index fe1508707..efc1696dd 100644 --- a/lib/dummy.h +++ b/lib/dummy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Nicira Networks. + * Copyright (c) 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,5 +23,6 @@ void dummy_enable(void); /* Implementation details. */ void dpif_dummy_register(void); void netdev_dummy_register(void); +void timeval_dummy_register(void); #endif /* dummy.h */ diff --git a/lib/timeval.c b/lib/timeval.c index bc7411fb9..c8c02bdc4 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -20,13 +20,16 @@ #include <errno.h> #include <poll.h> #include <signal.h> +#include <stdlib.h> #include <string.h> #include <sys/time.h> #include <sys/resource.h> #include <unistd.h> #include "coverage.h" +#include "dummy.h" #include "fatal-signal.h" #include "signals.h" +#include "unixctl.h" #include "util.h" #include "vlog.h" @@ -48,6 +51,9 @@ static volatile sig_atomic_t monotonic_tick = true; static struct timespec wall_time; static struct timespec monotonic_time; +/* Fixed monotonic time offset, for use by unit tests. */ +static struct timespec warp_offset; + /* Time at which to die with SIGALRM (if not TIME_MIN). */ static time_t deadline = TIME_MIN; @@ -62,6 +68,8 @@ static void unblock_sigalrm(const sigset_t *); static void log_poll_interval(long long int last_wakeup); static struct rusage *get_recent_rusage(void); static void refresh_rusage(void); +static void timespec_add(struct timespec *sum, + const struct timespec *a, const struct timespec *b); /* Initializes the timetracking module. * @@ -180,6 +188,7 @@ refresh_monotonic(void) refresh_wall_if_ticked(); monotonic_time = wall_time; } + timespec_add(&monotonic_time, &monotonic_time, &warp_offset); monotonic_tick = false; } @@ -408,6 +417,23 @@ timeval_diff_msec(const struct timeval *a, const struct timeval *b) } static void +timespec_add(struct timespec *sum, + const struct timespec *a, + const struct timespec *b) +{ + struct timespec tmp; + + tmp.tv_sec = a->tv_sec + b->tv_sec; + tmp.tv_nsec = a->tv_nsec + b->tv_nsec; + if (tmp.tv_nsec >= 1000 * 1000 * 1000) { + tmp.tv_nsec -= 1000 * 1000 * 1000; + tmp.tv_sec++; + } + + *sum = tmp; +} + +static void log_poll_interval(long long int last_wakeup) { static unsigned int mean_interval; /* In 16ths of a millisecond. */ @@ -522,3 +548,31 @@ get_cpu_usage(void) { return cpu_usage; } + +/* Unixctl interface. */ + +static void +timeval_warp_cb(struct unixctl_conn *conn, + int argc OVS_UNUSED, const char *argv[], void *aux OVS_UNUSED) +{ + struct timespec ts; + int msecs; + + msecs = atoi(argv[1]); + if (msecs <= 0) { + unixctl_command_reply(conn, 501, "invalid MSECS"); + return; + } + + ts.tv_sec = msecs / 1000; + ts.tv_nsec = (msecs % 1000) * 1000 * 1000; + timespec_add(&warp_offset, &warp_offset, &ts); + unixctl_command_reply(conn, 200, "warped"); +} + +void +timeval_dummy_register(void) +{ + unixctl_command_register("time/warp", "MSECS", 1, 1, + timeval_warp_cb, NULL); +} |