[ovs-dev] [PATCH 1/2] timeval: Don't require signals for time_alarm().
Ethan Jackson
ethan at nicira.com
Fri Oct 5 02:15:42 UTC 2012
Before this patch, time_alarm() used the SIGALRM handler to notify
the poll loop that it should exit the program. Instead, this patch
simply implements time_alarm() directly in the pool loop. This
significantly simplifies the code, while removing a call to
timer_create() which is not currently supported on ESX.
Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
lib/timeval.c | 63 ++++++++++++++++++++---------------------------------------
1 file changed, 21 insertions(+), 42 deletions(-)
diff --git a/lib/timeval.c b/lib/timeval.c
index 3d339e4..9b81cd3 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -58,15 +58,14 @@ static long long int boot_time;
static struct timespec warp_offset; /* Offset added to monotonic_time. */
static bool time_stopped; /* Disables real-time updates, if true. */
-/* Time at which to die with SIGALRM (if not TIME_MIN). */
-static time_t deadline = TIME_MIN;
+/* Time in milliseconds at which to die with SIGALRM (if not LLONG_MAX). */
+static long long int deadline = LLONG_MAX;
static void set_up_timer(void);
static void set_up_signal(int flags);
static void sigalrm_handler(int);
static void refresh_wall_if_ticked(void);
static void refresh_monotonic_if_ticked(void);
-static time_t time_add(time_t, time_t);
static void block_sigalrm(sigset_t *);
static void unblock_sigalrm(const sigset_t *);
static void log_poll_interval(long long int last_wakeup);
@@ -174,12 +173,6 @@ time_postfork(void)
if (CACHE_TIME) {
set_up_timer();
- } else {
- /* If we are not caching kernel time, the only reason the timer should
- * exist is if time_alarm() was called and deadline is set */
- if (deadline != TIME_MIN) {
- set_up_timer();
- }
}
}
@@ -228,17 +221,6 @@ time_now(void)
return monotonic_time.tv_sec;
}
-/* Same as time_now() except does not write to static variables, for use in
- * signal handlers. */
-static time_t
-time_now_sig(void)
-{
- struct timespec cur_time;
-
- clock_gettime(monotonic_clock, &cur_time);
- return cur_time.tv_sec;
-}
-
/* Returns the current time, in seconds. */
time_t
time_wall(void)
@@ -286,20 +268,20 @@ time_wall_timespec(struct timespec *ts)
void
time_alarm(unsigned int secs)
{
+ long long int now;
+ long long int msecs;
+
sigset_t oldsigs;
time_init();
+ time_refresh();
+
+ now = time_msec();
+ msecs = secs * 1000;
block_sigalrm(&oldsigs);
- deadline = secs ? time_add(time_now(), secs) : TIME_MIN;
+ deadline = now < LLONG_MAX - msecs ? now + msecs : LLONG_MAX;
unblock_sigalrm(&oldsigs);
-
- if (!CACHE_TIME) {
- /* If we aren't timing the gaps between kernel time refreshes we need to
- * to start the timer up now */
- set_up_signal(SA_RESTART);
- set_up_timer();
- }
}
/* Like poll(), except:
@@ -331,6 +313,9 @@ time_poll(struct pollfd *pollfds, int n_pollfds, long long int timeout_when,
coverage_clear();
start = time_msec();
blocked = false;
+
+ timeout_when = MIN(timeout_when, deadline);
+
for (;;) {
long long int now = time_msec();
int time_left;
@@ -347,12 +332,18 @@ time_poll(struct pollfd *pollfds, int n_pollfds, long long int timeout_when,
if (retval < 0) {
retval = -errno;
}
+
time_refresh();
+ if (deadline <= time_msec()) {
+ fatal_signal_handler(SIGALRM);
+ break;
+ }
+
if (retval != -EINTR) {
break;
}
- if (!blocked && deadline == TIME_MIN) {
+ if (!blocked && deadline == LLONG_MAX) {
block_sigalrm(&oldsigs);
blocked = true;
}
@@ -366,23 +357,11 @@ time_poll(struct pollfd *pollfds, int n_pollfds, long long int timeout_when,
return retval;
}
-/* Returns the sum of 'a' and 'b', with saturation on overflow or underflow. */
-static time_t
-time_add(time_t a, time_t b)
-{
- return (a >= 0
- ? (b > TIME_MAX - a ? TIME_MAX : a + b)
- : (b < TIME_MIN - a ? TIME_MIN : a + b));
-}
-
static void
-sigalrm_handler(int sig_nr)
+sigalrm_handler(int sig_nr OVS_UNUSED)
{
wall_tick = true;
monotonic_tick = true;
- if (deadline != TIME_MIN && time_now_sig() > deadline) {
- fatal_signal_handler(sig_nr);
- }
}
static void
--
1.7.12
More information about the dev
mailing list