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, ...)
{
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)
{
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;