X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Ftimeval.c;h=0ccfa42a38695359657a6449e3b9954bb479b3ae;hb=f80022d9df98d29ee41176a4bc6cb91025da84b8;hp=2f003552825919442ff0958099c9d4820764c627;hpb=6e97c6506ea22f300966d6210a2fa742a9e04e71;p=sliver-openvswitch.git diff --git a/lib/timeval.c b/lib/timeval.c index 2f0035528..0ccfa42a3 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -17,9 +17,6 @@ #include #include "timeval.h" #include -#if HAVE_EXECINFO_H -#include -#endif #include #include #include @@ -33,11 +30,21 @@ #include "fatal-signal.h" #include "hash.h" #include "hmap.h" +#include "ovs-thread.h" #include "signals.h" #include "unixctl.h" #include "util.h" #include "vlog.h" +/* backtrace() from is really useful, but it is not signal safe + * everywhere, such as on x86-64. */ +#if HAVE_BACKTRACE && !defined __x86_64__ +# define USE_BACKTRACE 1 +# include +#else +# define USE_BACKTRACE 0 +#endif + VLOG_DEFINE_THIS_MODULE(timeval); /* The clock to use for measuring time intervals. This is CLOCK_MONOTONIC by @@ -93,9 +100,7 @@ static void timespec_add(struct timespec *sum, const struct timespec *a, const struct timespec *b); static unixctl_cb_func backtrace_cb; -#ifndef HAVE_EXECINFO_H -#define HAVE_EXECINFO_H 0 - +#if !USE_BACKTRACE static int backtrace(void **buffer OVS_UNUSED, int size OVS_UNUSED) { @@ -107,7 +112,7 @@ backtrace_symbols(void *const *buffer OVS_UNUSED, int size OVS_UNUSED) { NOT_REACHED(); } -#endif +#endif /* !USE_BACKTRACE */ /* Initializes the timetracking module, if not already initialized. */ static void @@ -124,7 +129,7 @@ time_init(void) * initialization which is not signal safe. This can cause deadlocks if * run from the signal handler. As a workaround, force the initialization * to happen here. */ - if (HAVE_EXECINFO_H) { + if (USE_BACKTRACE) { void *bt[1]; backtrace(bt, ARRAY_SIZE(bt)); @@ -132,7 +137,7 @@ time_init(void) memset(traces, 0, sizeof traces); - if (HAVE_EXECINFO_H && CACHE_TIME) { + if (USE_BACKTRACE && CACHE_TIME) { unixctl_command_register("backtrace", "", 0, 0, backtrace_cb, NULL); } @@ -163,35 +168,6 @@ set_up_signal(int flags) xsigaction(SIGALRM, &sa, NULL); } -/* Remove SA_RESTART from the flags for SIGALRM, so that any system call that - * is interrupted by the periodic timer interrupt will return EINTR instead of - * continuing after the signal handler returns. - * - * time_disable_restart() and time_enable_restart() may be usefully wrapped - * around function calls that might otherwise block forever unless interrupted - * by a signal, e.g.: - * - * time_disable_restart(); - * fcntl(fd, F_SETLKW, &lock); - * time_enable_restart(); - */ -void -time_disable_restart(void) -{ - time_init(); - set_up_signal(0); -} - -/* Add SA_RESTART to the flags for SIGALRM, so that any system call that - * is interrupted by the periodic timer interrupt will continue after the - * signal handler returns instead of returning EINTR. */ -void -time_enable_restart(void) -{ - time_init(); - set_up_signal(SA_RESTART); -} - static void set_up_timer(void) { @@ -203,7 +179,7 @@ set_up_timer(void) } if (timer_create(monotonic_clock, NULL, &timer_id)) { - VLOG_FATAL("timer_create failed (%s)", strerror(errno)); + VLOG_FATAL("timer_create failed (%s)", ovs_strerror(errno)); } itimer.it_interval.tv_sec = 0; @@ -211,7 +187,7 @@ set_up_timer(void) itimer.it_value = itimer.it_interval; if (timer_settime(timer_id, 0, &itimer, NULL)) { - VLOG_FATAL("timer_settime failed (%s)", strerror(errno)); + VLOG_FATAL("timer_settime failed (%s)", ovs_strerror(errno)); } } @@ -322,17 +298,13 @@ time_alarm(unsigned int secs) long long int now; long long int msecs; - sigset_t oldsigs; - + assert_single_threaded(); time_init(); time_refresh(); now = time_msec(); msecs = secs * 1000LL; - - block_sigalrm(&oldsigs); deadline = now < LLONG_MAX - msecs ? now + msecs : LLONG_MAX; - unblock_sigalrm(&oldsigs); } /* Like poll(), except: @@ -419,7 +391,7 @@ sigalrm_handler(int sig_nr OVS_UNUSED) wall_tick = true; monotonic_tick = true; - if (HAVE_EXECINFO_H && CACHE_TIME) { + if (USE_BACKTRACE && CACHE_TIME) { struct trace *trace = &traces[trace_head]; trace->n_frames = backtrace(trace->backtrace, @@ -450,13 +422,13 @@ block_sigalrm(sigset_t *oldsigs) sigset_t sigalrm; sigemptyset(&sigalrm); sigaddset(&sigalrm, SIGALRM); - xsigprocmask(SIG_BLOCK, &sigalrm, oldsigs); + xpthread_sigmask(SIG_BLOCK, &sigalrm, oldsigs); } static void unblock_sigalrm(const sigset_t *oldsigs) { - xsigprocmask(SIG_SETMASK, oldsigs, NULL); + xpthread_sigmask(SIG_SETMASK, oldsigs, NULL); } long long int @@ -484,7 +456,7 @@ void xgettimeofday(struct timeval *tv) { if (gettimeofday(tv, NULL) == -1) { - VLOG_FATAL("gettimeofday failed (%s)", strerror(errno)); + VLOG_FATAL("gettimeofday failed (%s)", ovs_strerror(errno)); } } @@ -633,7 +605,7 @@ format_backtraces(struct ds *ds, size_t min_count) { time_init(); - if (HAVE_EXECINFO_H && CACHE_TIME) { + if (USE_BACKTRACE && CACHE_TIME) { struct hmap trace_map = HMAP_INITIALIZER(&trace_map); struct trace *trace, *next; sigset_t oldsigs; @@ -730,7 +702,7 @@ backtrace_cb(struct unixctl_conn *conn, { struct ds ds = DS_EMPTY_INITIALIZER; - ovs_assert(HAVE_EXECINFO_H && CACHE_TIME); + ovs_assert(USE_BACKTRACE && CACHE_TIME); format_backtraces(&ds, 0); unixctl_command_reply(conn, ds_cstr(&ds)); ds_destroy(&ds);