2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

timeval: Don't require signals for time_alarm().

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@nicira.com>
This commit is contained in:
Ethan Jackson
2012-10-04 17:57:16 -07:00
parent 1d446463ea
commit 00a1689587

View File

@@ -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,21 @@ 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);
if (retval < 0) {
retval = 0;
}
break;
}
if (retval != -EINTR) {
break;
}
if (!blocked && deadline == TIME_MIN) {
if (!blocked && !CACHE_TIME) {
block_sigalrm(&oldsigs);
blocked = true;
}
@@ -366,23 +360,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