summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_time.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2002-12-31 18:22:12 +0000
committersam <sam@FreeBSD.org>2002-12-31 18:22:12 +0000
commitedba43451786c581df1dd12ecf663a67cb2694e6 (patch)
tree4199710046cda2e6e9883c354b393d1aab021377 /sys/kern/kern_time.c
parent7057eb15ff1e91b11f7c3f310ca414b707263c1f (diff)
downloadFreeBSD-src-edba43451786c581df1dd12ecf663a67cb2694e6.zip
FreeBSD-src-edba43451786c581df1dd12ecf663a67cb2694e6.tar.gz
o reduce the overhead of calling ppsratecheck by using ticks instead of
calling getmicrouptime (but maintain the struct timeval-based calling convention for compatibility) o eliminate the use of timersub in ratecheck Note that flood ping tests indicate ppsratecheck is inaccurate (but on the conservative side) with this revised implementation. If more accuracy is needed we'll have to introduce an alternate interface or increase the overhead. Reviewed by: silby, dillon, bde
Diffstat (limited to 'sys/kern/kern_time.c')
-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