summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_time.c79
1 files changed, 24 insertions, 55 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 169d5e0..2d53d3f 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -664,21 +664,8 @@ timevalfix(struct timeval *t1)
}
}
-#ifndef timersub
-#define timersub(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
- if ((vvp)->tv_usec < 0) { \
- (vvp)->tv_sec--; \
- (vvp)->tv_usec += 1000000; \
- } \
- } while (0)
-#endif
-
/*
- * ratecheck(): simple time-based rate-limit checking. see ratecheck(9)
- * for usage and rationale.
+ * ratecheck(): simple time-based rate-limit checking.
*/
int
ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
@@ -686,8 +673,9 @@ ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
struct timeval tv, delta;
int rv = 0;
- getmicrouptime(&tv);
- timersub(&tv, lasttime, &delta);
+ getmicrouptime(&tv); /* NB: 10ms precision */
+ delta = tv;
+ timevalsub(&delta, lasttime);
/*
* check for 0,0 is so that the message will be seen at least once,
@@ -704,50 +692,31 @@ ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
/*
* ppsratecheck(): packets (or events) per second limitation.
+ *
+ * Return 0 if the limit is to be enforced (e.g. the caller
+ * should drop a packet because of the rate limitation).
+ *
+ * Note that we maintain the struct timeval for compatibility
+ * with other bsd systems. We reuse the storage and just monitor
+ * clock ticks for minimal overhead.
*/
int
ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
{
- struct timeval tv, delta;
- int rv;
-
- getmicrouptime(&tv);
- timersub(&tv, lasttime, &delta);
+ int now;
/*
- * check for 0,0 is so that the message will be seen at least once.
- * if more than one second have passed since the last update of
- * lasttime, reset the counter.
- *
- * we do increment *curpps even in *curpps < maxpps case, as some may
- * try to use *curpps for stat purposes as well.
+ * Reset the last time and counter if this is the first call
+ * or more than a second has passed since the last update of
+ * lasttime.
*/
- if ((lasttime->tv_sec == 0 && lasttime->tv_usec == 0) ||
- delta.tv_sec >= 1) {
- *lasttime = tv;
- *curpps = 0;
- rv = 1;
- } else if (maxpps < 0)
- rv = 1;
- else if (*curpps < maxpps)
- rv = 1;
- else
- rv = 0;
-
-#if 1 /*DIAGNOSTIC?*/
- /* be careful about wrap-around */
- if (*curpps + 1 > *curpps)
- *curpps = *curpps + 1;
-#else
- /*
- * assume that there's not too many calls to this function.
- * not sure if the assumption holds, as it depends on *caller's*
- * behavior, not the behavior of this function.
- * IMHO it is wrong to make assumption on the caller's behavior,
- * so the above #if is #if 1, not #ifdef DIAGNOSTIC.
- */
- *curpps = *curpps + 1;
-#endif
-
- return (rv);
+ now = ticks;
+ if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) {
+ lasttime->tv_sec = now;
+ *curpps = 1;
+ return (1);
+ } else {
+ (*curpps)++; /* NB: ignore potential overflow */
+ return (maxpps < 0 || *curpps < maxpps);
+ }
}
OpenPOWER on IntegriCloud