#include "fatal-signal.h"
#include "util.h"
+#include "vlog.h"
+#define THIS_MODULE VLM_timeval
+
/* Initialized? */
static bool inited;
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);
/* Initializes the timetracking module. */
void
int
time_poll(struct pollfd *pollfds, int n_pollfds, int timeout)
{
+ static long long int last_wakeup;
long long int start;
sigset_t oldsigs;
bool blocked;
int retval;
time_refresh();
+ log_poll_interval(last_wakeup);
start = time_msec();
blocked = false;
for (;;) {
if (blocked) {
unblock_sigalrm(&oldsigs);
}
+ last_wakeup = time_msec();
return retval;
}
ofp_fatal(errno, "sigprocmask");
}
}
+
+static void
+log_poll_interval(long long int last_wakeup)
+{
+ static unsigned int mean_interval; /* In 16ths of a millisecond. */
+ static unsigned int n_samples;
+
+ long long int now;
+ unsigned int interval; /* In 16ths of a millisecond. */
+
+ /* Compute interval from last wakeup to now in 16ths of a millisecond,
+ * capped at 10 seconds (16000 in this unit). */
+ now = time_msec();
+ interval = MIN(10000, now - last_wakeup) << 4;
+
+ /* Warn if we took too much time between polls. */
+ if (n_samples > 10 && interval > mean_interval * 8) {
+ VLOG_WARN("%u ms poll interval is over %u times "
+ "the weighted mean interval %u ms (%u samples)",
+ (interval + 8) / 16, interval / mean_interval,
+ (mean_interval + 8) / 16, n_samples);
+ }
+
+ /* Update exponentially weighted moving average. With these parameters, a
+ * given value decays to 1% of its value in about 100 time steps. */
+ if (n_samples++) {
+ mean_interval = (mean_interval * 122 + interval * 6 + 64) / 128;
+ } else {
+ mean_interval = interval;
+ }
+}