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
This commit is contained in:
parent
ae5c97aaed
commit
addea9d4d7
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user