Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support uint64 token bucket rates #378

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions elements/standard/ratedunqueue.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
46 changes: 23 additions & 23 deletions elements/test/biginttest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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];
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion include/click/bigint.hh
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ class Bigint { public:
};

/** @brief Typical Bigint usage with uint32_t limb_type. */
typedef Bigint<uint32_t> bigint;
typedef Bigint<uint64_t> bigint;

CLICK_ENDDECLS
#endif
10 changes: 5 additions & 5 deletions include/click/tokenbucket.hh
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void TokenRateX<P>::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;
}
Expand Down Expand Up @@ -1009,9 +1009,9 @@ inline typename TokenBucketX<P>::ticks_type TokenBucketX<P>::epochs_until_contai
* @brief Jiffy-based token bucket rate
*
* Equivalent to
* @link TokenRateX TokenRateX<TokenBucketJiffyParameters<unsigned> >@endlink.
* @link TokenRateX TokenRateX<TokenBucketJiffyParameters<unsigned long long> >@endlink.
* @sa TokenRateX, TokenBucketJiffyParameters */
typedef TokenRateX<TokenBucketJiffyParameters<unsigned> > TokenRate;
typedef TokenRateX<TokenBucketJiffyParameters<unsigned long long> > TokenRate;

/** @class TokenCounter include/click/tokenbucket.hh <click/tokenbucket.hh>
* @brief Jiffy-based token counter
Expand All @@ -1025,9 +1025,9 @@ typedef TokenCounterX<TokenRate> TokenCounter;
* @brief Jiffy-based token bucket rate limiter
*
* Equivalent to
* @link TokenBucketX TokenBucketX<TokenBucketJiffyParameters<unsigned> >@endlink.
* @link TokenBucketX TokenBucketX<TokenBucketJiffyParameters<unsigned long long> >@endlink.
* @sa TokenBucketX, TokenBucketJiffyParameters */
typedef TokenBucketX<TokenBucketJiffyParameters<unsigned> > TokenBucket;
typedef TokenBucketX<TokenBucketJiffyParameters<unsigned long long> > TokenBucket;

CLICK_ENDDECLS
#endif