[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Re: [PATCH] fix serial token buket
Stefano Stabellini wrote: > Using timespec in the serial token bucket causes problems with integer > overflows. > This patch fixes the issue using timeval instead of timespec variables, > everywhere but from reading the current time with clock_gettime. > Oops, I forgot one substitution. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> --- diff -r 0ea6bd53cfb6 hw/serial.c --- a/hw/serial.c Thu Oct 23 10:26:02 2008 +0100 +++ b/hw/serial.c Fri Nov 14 16:04:50 2008 +0000 @@ -155,8 +155,8 @@ doesn't kill dom0. Simple token bucket. If we get some actual data from the user, instantly refil the bucket. */ -/* How long it takes to generate a token, in nanoseconds. */ -#define TOKEN_PERIOD 1000000 +/* How long it takes to generate a token, in microseconds. */ +#define TOKEN_PERIOD 1000 /* Maximum and initial size of token bucket */ #define TOKENS_MAX 100000 @@ -279,16 +279,19 @@ static void serial_get_token(void) { - static struct timespec last_refil_time; + static struct timeval last_refil_time; static int started; assert(tokens_avail >= 0); if (!tokens_avail) { - struct timespec delta, now; + struct timespec now; + struct timeval delta; long generated; if (!started) { - clock_gettime(CLOCK_MONOTONIC, &last_refil_time); + clock_gettime(CLOCK_MONOTONIC, &now); + last_refil_time.tv_sec = now.tv_sec; + last_refil_time.tv_usec = now.tv_nsec / 1000; tokens_avail = TOKENS_MAX; started = 1; return; @@ -296,35 +299,35 @@ retry: clock_gettime(CLOCK_MONOTONIC, &now); delta.tv_sec = now.tv_sec - last_refil_time.tv_sec; - delta.tv_nsec = now.tv_nsec - last_refil_time.tv_nsec; - if (delta.tv_nsec < 0) { - delta.tv_nsec += 1000000000; + delta.tv_usec = (now.tv_nsec / 1000) - last_refil_time.tv_usec; + if (delta.tv_usec < 0) { + delta.tv_usec += 1000000; delta.tv_sec--; } - assert(delta.tv_nsec >= 0 && delta.tv_sec >= 0); - if (delta.tv_nsec < TOKEN_PERIOD) { + assert(delta.tv_usec >= 0 && delta.tv_sec >= 0); + if (delta.tv_sec == 0 && delta.tv_usec < TOKEN_PERIOD) { struct timespec ts; /* Wait until at least one token is available. */ - ts.tv_sec = TOKEN_PERIOD / 1000000000; - ts.tv_nsec = TOKEN_PERIOD % 1000000000; + ts.tv_sec = TOKEN_PERIOD / 1000000; + ts.tv_nsec = (TOKEN_PERIOD % 1000000) * 1000; while (nanosleep(&ts, &ts) < 0 && errno == EINTR) ; goto retry; } - if (delta.tv_sec >= 2) { + if (delta.tv_sec >= 2000) { /* avoid arithmetic overflow if it has been ages */ - delta.tv_sec = 2; - delta.tv_nsec = 0; + delta.tv_sec = 2000; + delta.tv_usec = 0; } - generated = (delta.tv_sec * 1000000000) / TOKEN_PERIOD; + generated = (delta.tv_sec * 1000000) / TOKEN_PERIOD; generated += - ((delta.tv_sec * 1000000000) % TOKEN_PERIOD + delta.tv_nsec) / TOKEN_PERIOD; + ((delta.tv_sec * 1000000) % TOKEN_PERIOD + delta.tv_usec) / TOKEN_PERIOD; assert(generated > 0); - last_refil_time.tv_nsec += (generated * TOKEN_PERIOD) % 1000000000; - last_refil_time.tv_sec += last_refil_time.tv_nsec / 1000000000; - last_refil_time.tv_nsec %= 1000000000; - last_refil_time.tv_sec += (generated * TOKEN_PERIOD) / 1000000000; + last_refil_time.tv_usec += (generated * TOKEN_PERIOD) % 1000000; + last_refil_time.tv_sec += last_refil_time.tv_usec / 1000000; + last_refil_time.tv_usec %= 1000000; + last_refil_time.tv_sec += (generated * TOKEN_PERIOD) / 1000000; if (generated > TOKENS_MAX) generated = TOKENS_MAX; tokens_avail = generated; _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |