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

TokenBucket: use 64bit if supported #179

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
6 changes: 3 additions & 3 deletions elements/standard/ratedsource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ RatedSource::configure(Vector<String> &conf, ErrorHandler *errh)
String data =
"Random bullshit in a packet, at least 64 bytes long. Well, now it is.";
unsigned rate = 10;
unsigned bandwidth = 0;
ucounter_t bandwidth = 0;
int limit = -1;
int datasize = -1;
bool active = true, stop = false;
Expand All @@ -62,11 +62,11 @@ RatedSource::configure(Vector<String> &conf, ErrorHandler *errh)
.read_p("RATE", rate)
.read_p("LIMIT", limit)
.read_p("ACTIVE", active)
.read("HEADROOM", _headroom)
.read("HEADROOM", _headroom)
.read("LENGTH", datasize)
.read("DATASIZE", datasize) // deprecated
.read("STOP", stop)
.read("BANDWIDTH", BandwidthArg(), bandwidth)
.read("BANDWIDTH", bandwidth_arg_t(), bandwidth)
.read("END_CALL", HandlerCallArg(HandlerCall::writable), end_h)
.complete() < 0)
return -1;
Expand Down
33 changes: 24 additions & 9 deletions elements/standard/ratedsource.hh
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
#ifndef CLICK_RATEDSOURCE_HH
#define CLICK_RATEDSOURCE_HH
#include <click/batchelement.hh>
#include <click/tokenbucket.hh>
#if HAVE_INT64_TYPES
# include <click/tokenbucket64.hh>
#else
# include <click/tokenbucket.hh>
#endif
#include <click/task.hh>
#include <click/notifier.hh>
CLICK_DECLS
class HandlerCall;


#if HAVE_INT64_TYPES
class Bandwidth64Arg;
#else
class BandwidthArg;
#endif

/*
=c

Expand Down Expand Up @@ -120,15 +131,19 @@ class RatedSource : public BatchElement, public ActiveNotifier {
static const unsigned NO_LIMIT = 0xFFFFFFFFU;
static const unsigned DEF_BATCH_SIZE = 32;

#if HAVE_INT64_TYPES
typedef uint64_t ucounter_t;
typedef int64_t counter_t;
#else
typedef uint32_t ucounter_t;
typedef int32_t counter_t;
#endif
#if HAVE_INT64_TYPES
typedef uint64_t ucounter_t;
typedef int64_t counter_t;
typedef TokenBucket64 token_bucket_t;
typedef Bandwidth64Arg bandwidth_arg_t;
#else
typedef uint32_t ucounter_t;
typedef int32_t counter_t;
typedef TokenBucket token_bucket_t;
typedef BandwidthArg bandwidth_arg_t;
#endif

TokenBucket _tb;
token_bucket_t _tb;
ucounter_t _count;
ucounter_t _limit;
#if HAVE_BATCH
Expand Down
6 changes: 5 additions & 1 deletion elements/standard/ratedsplitter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#define CLICK_RATEDSPLITTER_HH
#include <click/element.hh>
#include <click/batchelement.hh>
#include <click/tokenbucket.hh>
#include <click/tokenbucket64.hh>
CLICK_DECLS

/*
Expand Down Expand Up @@ -84,7 +84,11 @@ class RatedSplitter : public BatchElement { public:

protected:

#if HAVE_INT64_TYPES
TokenBucket64 _tb;
#else
TokenBucket _tb;
#endif

static String read_handler(Element *, void *) CLICK_COLD;

Expand Down
21 changes: 13 additions & 8 deletions elements/standard/ratedunqueue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ RatedUnqueue::configure(Vector<String> &conf, ErrorHandler *errh)
}

int
RatedUnqueue::configure_helper(TokenBucket *tb, bool is_bandwidth, Element *elt, Vector<String> &conf, ErrorHandler *errh)
RatedUnqueue::configure_helper(token_bucket_t *tb, bool is_bandwidth, Element *elt, Vector<String> &conf, ErrorHandler *errh)
{
unsigned r;
ucounter_t r;
unsigned dur_msec = 20;
unsigned tokens;
ucounter_t 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);
args.read_mp("RATE", bandwidth_arg_t(), r);
else
args.read_mp("RATE", r);
if (args.read("BURST_DURATION", SecondsArg(3), dur_msec).read_status(dur_specified)
Expand All @@ -65,17 +65,22 @@ RatedUnqueue::configure_helper(TokenBucket *tb, bool is_bandwidth, Element *elt,
return -1;

if (dur_specified && tokens_specified)
return errh->error("cannot specify both BURST_DURATION and BURST_SIZE");
return errh->error("cannot specify both BURST_DURATION and BURST_SIZE");
else if (!tokens_specified) {
#if !HAVE_INT64_TYPES
bigint::limb_type res[2];
bigint::multiply(res[1], res[0], r, dur_msec);
bigint::divide(res, res, 2, 1000);
tokens = res[1] ? UINT_MAX : res[0];
#else
ucounter_t l = r * (ucounter_t)dur_msec;
tokens = l / 1000;
#endif
}

if (is_bandwidth) {
unsigned new_tokens = tokens + tb_bandwidth_thresh;
tokens = (tokens < new_tokens ? new_tokens : UINT_MAX);
ucounter_t new_tokens = tokens + tb_bandwidth_thresh;
tokens = (tokens < new_tokens ? new_tokens : UINT64_MAX);
}

tb->assign(r, tokens ? tokens : 1);
Expand All @@ -98,7 +103,7 @@ RatedUnqueue::run_task(Task *)
_runs++;

if (!_active)
return false;
return false;

_tb.refill();
if (_tb.contains(1)) {
Expand Down
41 changes: 32 additions & 9 deletions elements/standard/ratedunqueue.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@
#ifndef CLICK_RATEDUNQUEUE_HH
#define CLICK_RATEDUNQUEUE_HH
#include <click/batchelement.hh>
#include <click/tokenbucket.hh>
#if HAVE_INT64_TYPES
# include <click/tokenbucket64.hh>
#else
# include <click/tokenbucket.hh>
#endif
#include <click/task.hh>
#include <click/timer.hh>
#include <click/notifier.hh>
CLICK_DECLS

#if HAVE_INT64_TYPES
class Bandwidth64Arg;
#else
class BandwidthArg;
#endif

/*
* =c
* RatedUnqueue(RATE, I[<KEYWORDS>])
Expand Down Expand Up @@ -51,8 +61,20 @@ class RatedUnqueue : public BatchElement { public:
const char *processing() const { return PULL_TO_PUSH; }
bool is_bandwidth() const { return class_name()[0] == 'B'; }

#if HAVE_INT64_TYPES
typedef uint64_t ucounter_t;
typedef int64_t counter_t;
typedef TokenBucket64 token_bucket_t;
typedef Bandwidth64Arg bandwidth_arg_t;
#else
typedef uint32_t ucounter_t;
typedef int32_t counter_t;
typedef TokenBucket token_bucket_t;
typedef BandwidthArg bandwidth_arg_t;
#endif

int configure(Vector<String> &, ErrorHandler *) CLICK_COLD;
static int configure_helper(TokenBucket *tb, bool is_bandwidth, Element *elt, Vector<String> &conf, ErrorHandler *errh);
static int configure_helper(token_bucket_t *tb, bool is_bandwidth, Element *elt, Vector<String> &conf, ErrorHandler *errh);
enum { tb_bandwidth_thresh = 131072 };

bool can_live_reconfigure() const { return true; }
Expand All @@ -63,16 +85,17 @@ class RatedUnqueue : public BatchElement { public:

protected:

TokenBucket _tb;
token_bucket_t _tb;
Task _task;
Timer _timer;
NotifierSignal _signal;
uint32_t _runs;
uint32_t _packets;
uint32_t _pushes;
uint32_t _failed_pulls;
uint32_t _empty_runs;
uint32_t _burst;
ucounter_t _runs;
ucounter_t _packets;
ucounter_t _pushes;
ucounter_t _failed_pulls;
ucounter_t _empty_runs;

unsigned _burst;

enum { h_calls, h_rate };

Expand Down
11 changes: 11 additions & 0 deletions include/click/args.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,17 @@ class BandwidthArg : public NumArg { public:
int status;
};

/** @class Bandwidth64Arg
@brief Parser class for 64bit bandwidth specifications.

Handles suffixes such as "Gbps", "k", etc. */
class Bandwidth64Arg : public NumArg { public:
bool parse(const String &str, uint64_t &result, const ArgContext & = blank_args);
static String unparse(uint64_t x);
int status;
};



/** @class BitvectorArg **/
class BitvectorArg { public:
Expand Down
Loading