From ae4e5b98245169dc02c12138d4acc69ce7da0261 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 16 Apr 2018 15:02:51 -0400 Subject: [PATCH] token: Fix uint32_t to uint64_t conversion Unfortunately, the units passed to monotime_coarse_stamp_units_to_approx_msec() was always 0 due to a type conversion. Signed-off-by: David Goulet --- src/common/token_bucket.c | 5 +++-- src/common/token_bucket.h | 3 +++ src/test/test_bwmgt.c | 23 +++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/common/token_bucket.c b/src/common/token_bucket.c index 5d97a920fb..d18731b0e3 100644 --- a/src/common/token_bucket.c +++ b/src/common/token_bucket.c @@ -108,7 +108,7 @@ token_bucket_raw_dec(token_bucket_raw_t *bucket, } /** Convert a rate in bytes per second to a rate in bytes per step */ -static uint32_t +STATIC uint32_t rate_per_sec_to_rate_per_step(uint32_t rate) { /* @@ -117,8 +117,9 @@ rate_per_sec_to_rate_per_step(uint32_t rate) (rate / 1000) * to_approximate_msec(TICKS_PER_STEP). But to minimize rounding error, we do it this way instead, and divide last. */ + uint64_t units = (uint64_t) rate * TICKS_PER_STEP; uint32_t val = (uint32_t) - monotime_coarse_stamp_units_to_approx_msec(rate*TICKS_PER_STEP)/1000; + monotime_coarse_stamp_units_to_approx_msec(units) / 1000; return val ? val : 1; } diff --git a/src/common/token_bucket.h b/src/common/token_bucket.h index 329b652f8e..fb5d9fc60a 100644 --- a/src/common/token_bucket.h +++ b/src/common/token_bucket.h @@ -10,6 +10,7 @@ #define TOR_TOKEN_BUCKET_H #include "torint.h" +#include "testsupport.h" /** Largest allowable burst value for a token buffer. */ #define TOKEN_BUCKET_MAX_BURST INT32_MAX @@ -109,6 +110,8 @@ token_bucket_rw_get_write(const token_bucket_rw_t *bucket) * a power of two if you can. */ #define TICKS_PER_STEP 16 +STATIC uint32_t rate_per_sec_to_rate_per_step(uint32_t rate); + #endif #endif /* TOR_TOKEN_BUCKET_H */ diff --git a/src/test/test_bwmgt.c b/src/test/test_bwmgt.c index 0579b4a419..268917005e 100644 --- a/src/test/test_bwmgt.c +++ b/src/test/test_bwmgt.c @@ -16,6 +16,7 @@ // an imaginary time, in timestamp units. Chosen so it will roll over. static const uint32_t START_TS = UINT32_MAX-10; static const int32_t KB = 1024; +static const uint32_t GB = (U64_LITERAL(1) << 30); static void test_bwmgt_token_buf_init(void *arg) @@ -192,6 +193,27 @@ test_bwmgt_token_buf_refill(void *arg) ; } +/* Test some helper functions we use within the token bucket interface. */ +static void +test_bwmgt_token_buf_helpers(void *arg) +{ + uint32_t ret; + + (void) arg; + + /* The returned value will be OS specific but in any case, it should be + * greater than 1 since we are passing 1GB/sec rate. */ + ret = rate_per_sec_to_rate_per_step(1 * GB); + tt_u64_op(ret, OP_GT, 1); + + /* We default to 1 in case rate is 0. */ + ret = rate_per_sec_to_rate_per_step(0); + tt_u64_op(ret, OP_EQ, 1); + + done: + ; +} + #define BWMGT(name) \ { #name, test_bwmgt_ ## name , 0, NULL, NULL } @@ -200,6 +222,7 @@ struct testcase_t bwmgt_tests[] = { BWMGT(token_buf_adjust), BWMGT(token_buf_dec), BWMGT(token_buf_refill), + BWMGT(token_buf_helpers), END_OF_TESTCASES };