From 54d37ca7193f30cc93f71884abc6fbc32245511a Mon Sep 17 00:00:00 2001 From: "Georgios P. Katsikas" Date: Fri, 24 Mar 2023 09:41:55 +0200 Subject: [PATCH] feat: support uint64 token bucket rates Signed-off-by: Georgios P. Katsikas --- elements/standard/ratedunqueue.hh | 10 +++---- elements/test/biginttest.cc | 46 +++++++++++++++---------------- include/click/bigint.hh | 2 +- include/click/tokenbucket.hh | 10 +++---- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/elements/standard/ratedunqueue.hh b/elements/standard/ratedunqueue.hh index c824b62b3e..3555e70c59 100644 --- a/elements/standard/ratedunqueue.hh +++ b/elements/standard/ratedunqueue.hh @@ -69,11 +69,11 @@ class RatedUnqueue : public BatchElement { public: Task _task; Timer _timer; NotifierSignal _signal; - uint32_t _runs; - uint32_t _packets; - uint32_t _pushes; - uint32_t _failed_pulls; - uint32_t _empty_runs; + uint64_t _runs; + uint64_t _packets; + uint64_t _pushes; + uint64_t _failed_pulls; + uint64_t _empty_runs; uint32_t _burst; enum { h_calls, h_rate }; diff --git a/elements/test/biginttest.cc b/elements/test/biginttest.cc index 1c734c3b3c..c8f6478379 100644 --- a/elements/test/biginttest.cc +++ b/elements/test/biginttest.cc @@ -36,8 +36,8 @@ BigintTest::BigintTest() #define CHECK(x, a, b) if (!(x)) return errh->error("%s:%d: test `%s' failed [%llu, %u]", __FILE__, __LINE__, #x, a, b); #define CHECK0(x) if (!(x)) return errh->error("%s:%d: test `%s' failed", __FILE__, __LINE__, #x); -static bool test_multiply(uint32_t a, uint32_t b, ErrorHandler *errh) { - uint32_t x[2]; +static bool test_multiply(uint64_t a, uint64_t b, ErrorHandler *errh) { + uint64_t x[2]; bigint::multiply(x[1], x[0], a, b); uint64_t c = (((uint64_t) x[1]) << 32) | x[0]; if (c != (uint64_t) a * b) { @@ -47,11 +47,11 @@ static bool test_multiply(uint32_t a, uint32_t b, ErrorHandler *errh) { return true; } -static bool test_mul(uint64_t a, uint32_t b, ErrorHandler *errh) { - uint32_t ax[2]; +static bool test_mul(uint64_t a, uint64_t b, ErrorHandler *errh) { + uint64_t ax[2]; ax[0] = a; ax[1] = a >> 32; - uint32_t cx[2]; + uint64_t cx[2]; cx[0] = cx[1] = 0; bigint::multiply_add(cx, ax, 2, b); uint64_t c = (((uint64_t) cx[1]) << 32) | cx[0]; @@ -62,11 +62,11 @@ static bool test_mul(uint64_t a, uint32_t b, ErrorHandler *errh) { return true; } -static bool test_div(uint64_t a, uint32_t b, ErrorHandler *errh) { - uint32_t ax[4]; +static bool test_div(uint64_t a, uint64_t b, ErrorHandler *errh) { + uint64_t ax[4]; ax[0] = a; ax[1] = a >> 32; - uint32_t r = bigint::divide(ax+2, ax, 2, b); + uint64_t r = bigint::divide(ax+2, ax, 2, b); uint64_t c = ((uint64_t) ax[3] << 32) | ax[2]; if (c != a / b) { errh->error("%llu / %u == %llu, not %llu", a, b, a * b, c); @@ -79,22 +79,22 @@ static bool test_div(uint64_t a, uint32_t b, ErrorHandler *errh) { return true; } -static bool test_inverse(uint32_t a, ErrorHandler *errh) { - assert(a & (1 << 31)); - uint32_t a_inverse = bigint::inverse(a); +static bool test_inverse(uint64_t a, ErrorHandler *errh) { + assert(a & (1 << 63)); + uint64_t a_inverse = bigint::inverse(a); // "Inverse is floor((b * (b - a) - 1) / a), where b = 2^32." uint64_t b = (uint64_t) 1 << 32; uint64_t want_inverse = (b * (b - a) - 1) / a; assert(want_inverse < b); if (a_inverse != want_inverse) { - errh->error("inverse(%u) == %u, not %u", a, (uint32_t) want_inverse, a_inverse); + errh->error("inverse(%u) == %u, not %u", a, (uint64_t) want_inverse, a_inverse); return false; } return true; } static bool test_add(uint64_t a, uint64_t b, ErrorHandler *errh) { - uint32_t ax[6]; + uint64_t ax[6]; ax[2] = a; ax[3] = a >> 32; ax[4] = b; @@ -112,35 +112,35 @@ int BigintTest::initialize(ErrorHandler *errh) { for (int i = 0; i < 3000; i++) { - uint32_t a = click_random() | (click_random() << 31); - uint32_t b = click_random() | (click_random() << 31); + uint64_t a = click_random() | (click_random() << 63); + uint64_t b = click_random() | (click_random() << 63); CHECK(test_multiply(a, b, errh), a, b); CHECK(test_mul(a, b, errh), a, b); } for (int i = 0; i < 8000; i++) { - uint32_t a = click_random(); + uint64_t a = click_random(); CHECK0(test_inverse(a | 0x80000000, errh)); } CHECK0(test_inverse(0x80000000, errh)); for (int i = 0; i < 8000; i++) { - uint64_t a = click_random() | ((uint64_t) click_random() << 31) | ((uint64_t) click_random() << 62); - uint64_t b = click_random() | ((uint64_t) click_random() << 31) | ((uint64_t) click_random() << 62); + uint64_t a = click_random() | ((uint64_t) click_random() << 63); + uint64_t b = click_random() | ((uint64_t) click_random() << 63); CHECK0(test_add(a, b, errh)); } CHECK0(test_div(12884758640815563913ULL, 2506284098U, errh)); for (int i = 0; i < 3000; i++) { - uint64_t a = click_random() | ((uint64_t) click_random() << 31) | ((uint64_t) click_random() << 62); - uint32_t b = click_random(); + uint64_t a = click_random() | ((uint64_t) click_random() << 63); + uint64_t b = click_random(); CHECK(test_div(a, b | 0x80000000, errh), a, b | 0x80000000); } for (int i = 0; i < 3000; i++) { - uint64_t a = click_random() | ((uint64_t) click_random() << 31) | ((uint64_t) click_random() << 62); - uint32_t b = click_random(); + uint64_t a = click_random() | ((uint64_t) click_random() << 63); + uint64_t b = click_random(); CHECK(test_div(a, b & ~0x80000000, errh), a, b & ~0x80000000); CHECK(test_div(a, b | 0x80000000, errh), a, b | 0x80000000); } - uint32_t x[3] = { 3481, 592182, 3024921038U }; + uint64_t x[3] = { 3481, 592182, 3024921038U }; CHECK0(bigint::unparse_clear(x, 3) == "55799944231168388787108580761"); x[0] = 10; diff --git a/include/click/bigint.hh b/include/click/bigint.hh index de00f75e10..0ff2287115 100644 --- a/include/click/bigint.hh +++ b/include/click/bigint.hh @@ -385,7 +385,7 @@ class Bigint { public: }; /** @brief Typical Bigint usage with uint32_t limb_type. */ -typedef Bigint bigint; +typedef Bigint bigint; CLICK_ENDDECLS #endif diff --git a/include/click/tokenbucket.hh b/include/click/tokenbucket.hh index 5966e9bbf7..d86b936a55 100644 --- a/include/click/tokenbucket.hh +++ b/include/click/tokenbucket.hh @@ -214,7 +214,7 @@ void TokenRateX

::assign(token_type rate, token_type capacity) token_type frequency = P::frequency(); if (rate != 0) { // constrain capacity so _tokens_per_tick fits in 1 limb - unsigned min_capacity = (rate - 1) / frequency + 1; + unsigned long long min_capacity = (rate - 1) / frequency + 1; if (capacity < min_capacity) capacity = min_capacity; } @@ -1009,9 +1009,9 @@ inline typename TokenBucketX

::ticks_type TokenBucketX

::epochs_until_contai * @brief Jiffy-based token bucket rate * * Equivalent to - * @link TokenRateX TokenRateX >@endlink. + * @link TokenRateX TokenRateX >@endlink. * @sa TokenRateX, TokenBucketJiffyParameters */ -typedef TokenRateX > TokenRate; +typedef TokenRateX > TokenRate; /** @class TokenCounter include/click/tokenbucket.hh * @brief Jiffy-based token counter @@ -1025,9 +1025,9 @@ typedef TokenCounterX TokenCounter; * @brief Jiffy-based token bucket rate limiter * * Equivalent to - * @link TokenBucketX TokenBucketX >@endlink. + * @link TokenBucketX TokenBucketX >@endlink. * @sa TokenBucketX, TokenBucketJiffyParameters */ -typedef TokenBucketX > TokenBucket; +typedef TokenBucketX > TokenBucket; CLICK_ENDDECLS #endif