Skip to content

Commit

Permalink
feat: support uint64 token bucket rates
Browse files Browse the repository at this point in the history
Signed-off-by: Georgios P. Katsikas <[email protected]>
  • Loading branch information
Georgios P. Katsikas committed Mar 24, 2023
1 parent ef86efe commit a922a21
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 41 deletions.
9 changes: 2 additions & 7 deletions elements/standard/ratedunqueue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,15 @@ RatedUnqueue::configure(Vector<String> &conf, ErrorHandler *errh)
int
RatedUnqueue::configure_helper(TokenBucket *tb, bool is_bandwidth, Element *elt, Vector<String> &conf, ErrorHandler *errh)
{
unsigned r;
uint64_t r;
unsigned dur_msec = 20;
unsigned tokens;
bool dur_specified, tokens_specified;
const char *burst_size = is_bandwidth ? "BURST_BYTES" : "BURST_SIZE";

Args args(conf, elt, errh);
if (is_bandwidth)
args.read_mp("RATE", BandwidthArg(), r);
else
args.read_mp("RATE", r);

if (args.read("BURST_DURATION", SecondsArg(3), dur_msec).read_status(dur_specified)
.read(burst_size, tokens).read_status(tokens_specified)
.complete() < 0)
Expand Down Expand Up @@ -147,9 +145,6 @@ RatedUnqueue::read_handler(Element *e, void *thunk)
RatedUnqueue *ru = (RatedUnqueue *)e;
switch ((uintptr_t) thunk) {
case h_rate:
if (ru->is_bandwidth())
return BandwidthArg::unparse(ru->_tb.rate());
else
return String(ru->_tb.rate());
case h_calls: {
StringAccum sa;
Expand Down
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

0 comments on commit a922a21

Please sign in to comment.