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:
@@ -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
|
||||
|
Reference in New Issue
Block a user