|
|
@@ -185,48 +185,6 @@ static void fatal(const char *format, ...)
|
|
|
static void badusage(const char *msg)
|
|
|
NONRETURNING;
|
|
|
|
|
|
-/* This next part serves only to construct the TVCALC macro, which
|
|
|
- * is used for doing arithmetic on struct timeval's. It works like this:
|
|
|
- * TVCALC(result, expression);
|
|
|
- * where result is a struct timeval (and must be an lvalue) and
|
|
|
- * expression is the single expression for both components. In this
|
|
|
- * expression you can use the special values TVELEM, which when fed a
|
|
|
- * const struct timeval* gives you the relevant component, and
|
|
|
- * TVADJUST. TVADJUST is necessary when subtracting timevals, to make
|
|
|
- * it easier to renormalise. Whenver you subtract timeval elements,
|
|
|
- * you must make sure that TVADJUST is added to the result of the
|
|
|
- * subtraction (before any resulting multiplication or what have you).
|
|
|
- * TVELEM must be linear in TVADJUST.
|
|
|
- */
|
|
|
-typedef long tvselector(const struct timeval*);
|
|
|
-
|
|
|
-static long
|
|
|
-tvselector_sec(const struct timeval *tv)
|
|
|
-{
|
|
|
- return tv->tv_sec;
|
|
|
-}
|
|
|
-
|
|
|
-static long
|
|
|
-tvselector_usec(const struct timeval *tv)
|
|
|
-{
|
|
|
- return tv->tv_usec;
|
|
|
-}
|
|
|
-
|
|
|
-#define TVCALC_ELEM(result, expr, sec, adj) \
|
|
|
-{ \
|
|
|
- const long TVADJUST = adj; \
|
|
|
- long (*const TVELEM)(const struct timeval *) = tvselector_##sec; \
|
|
|
- (result).tv_##sec = (expr); \
|
|
|
-}
|
|
|
-#define TVCALC(result, expr) \
|
|
|
-do { \
|
|
|
- TVCALC_ELEM(result, expr, sec, (-1)); \
|
|
|
- TVCALC_ELEM(result, expr, usec, (+1000000)); \
|
|
|
- (result).tv_sec += (result).tv_usec / 1000000; \
|
|
|
- (result).tv_usec %= 1000000; \
|
|
|
-} while (0)
|
|
|
-
|
|
|
-
|
|
|
static void
|
|
|
fatal(const char *format, ...)
|
|
|
{
|
|
|
@@ -257,6 +215,29 @@ xgettimeofday(struct timeval *tv)
|
|
|
if (gettimeofday(tv, NULL) != 0)
|
|
|
fatal("gettimeofday failed: %s", strerror(errno));
|
|
|
}
|
|
|
+
|
|
|
+static void
|
|
|
+tsub(struct timeval *r, struct timeval *a, struct timeval *b)
|
|
|
+{
|
|
|
+ r->tv_sec = (time_t)(a->tv_sec - b->tv_sec);
|
|
|
+ r->tv_usec = (suseconds_t)(a->tv_usec - b->tv_usec);
|
|
|
+ if (r->tv_usec < 0) {
|
|
|
+ --r->tv_sec;
|
|
|
+ r->tv_usec += 1000000;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+tmul(struct timeval *a, int b)
|
|
|
+{
|
|
|
+ a->tv_sec *= b;
|
|
|
+ a->tv_usec *= b;
|
|
|
+ if (a->tv_usec >= 1000000) {
|
|
|
+ ++a->tv_sec;
|
|
|
+ a->tv_usec -= 1000000;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static long
|
|
|
get_open_fd_max(void)
|
|
|
{
|
|
|
@@ -1219,10 +1200,12 @@ run_stop_schedule(void)
|
|
|
if (ratio < 10)
|
|
|
ratio++;
|
|
|
|
|
|
- TVCALC(interval, TVELEM(&after) * ratio -
|
|
|
- TVELEM(&before) + TVADJUST);
|
|
|
- TVCALC(maxinterval, TVELEM(&stopat) -
|
|
|
- TVELEM(&after) + TVADJUST);
|
|
|
+ tsub(&maxinterval, &stopat, &after);
|
|
|
+ tsub(&interval, &after, &before);
|
|
|
+ tmul(&interval, ratio);
|
|
|
+
|
|
|
+ if (interval.tv_sec < 0 || interval.tv_usec < 0)
|
|
|
+ interval.tv_sec = interval.tv_usec = 0;
|
|
|
|
|
|
if (timercmp(&interval, &maxinterval, >))
|
|
|
interval = maxinterval;
|