Skip to content

Commit

Permalink
Support bandwidths which must be represented as 64-bit integers
Browse files Browse the repository at this point in the history
  • Loading branch information
mihaibrodschi committed Aug 21, 2024
1 parent 00814a3 commit d81fded
Show file tree
Hide file tree
Showing 20 changed files with 63 additions and 63 deletions.
2 changes: 1 addition & 1 deletion elements/ip/iprewriterbase.hh
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ template<class T> inline IPRewriterEntry *
IPRewriterBase::search_migrate_entry(const IPFlowID &flowid, per_thread<T> &vstate)
{
//If the flow does not exist, it may be in other thread's stack if there was a migration
if (vstate->rebalance > 0 && click_jiffies() - vstate->rebalance < THREAD_MIGRATION_TIMEOUT * CLICK_HZ ) {
if (vstate->rebalance > 0 && click_jiffies() - vstate->rebalance < (uint64_t) THREAD_MIGRATION_TIMEOUT * CLICK_HZ ) {
//Search in other thread's stacks for the flow
for (int i = 0; i < vstate.weight(); i++) {
if (vstate.get_mapping(i) == click_current_cpu_id())
Expand Down
8 changes: 4 additions & 4 deletions elements/standard/bandwidthmeter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ BandwidthMeter::configure(Vector<String> &conf, ErrorHandler *errh)
if (conf.size() == 0)
return errh->error("too few arguments to BandwidthMeter(bandwidth, ...)");

Vector<unsigned> vals(conf.size(), 0);
Vector<uint64_t> vals(conf.size(), 0);
BandwidthArg ba;
for (int i = 0; i < conf.size(); i++)
if (!ba.parse(conf[i], vals[i]))
Expand All @@ -63,8 +63,8 @@ BandwidthMeter::configure(Vector<String> &conf, ErrorHandler *errh)
_meter1 = vals[0];
_nmeters = 1;
} else {
_meters = new unsigned[vals.size()];
memcpy(_meters, &vals[0], vals.size() * sizeof(int));
_meters = new uint64_t[vals.size()];
memcpy(_meters, &vals[0], vals.size() * sizeof(uint64_t));
_nmeters = vals.size();
}

Expand All @@ -83,7 +83,7 @@ BandwidthMeter::push(int, Packet *p)
int n = (r >= _meter1);
output(n).push(p);
} else {
unsigned *meters = _meters;
uint64_t *meters = _meters;
int nmeters = _nmeters;
for (int i = 0; i < nmeters; i++)
if (r < meters[i]) {
Expand Down
4 changes: 2 additions & 2 deletions elements/standard/bandwidthmeter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class BandwidthMeter : public Element { protected:

RateEWMA _rate;

unsigned _meter1;
unsigned *_meters;
uint64_t _meter1;
uint64_t *_meters;
int _nmeters;

static String meters_read_handler(Element *, void *) CLICK_COLD;
Expand Down
2 changes: 1 addition & 1 deletion elements/standard/linkunqueue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ LinkUnqueue::write_handler(const String &s, Element *e, void *thunk, ErrorHandle
break;
}
case H_BANDWIDTH: {
uint32_t bw;
uint64_t bw;
if (!cp_bandwidth(s, &bw)) {
return errh->error("invalid bandwidth");
} else if (bw < 100) {
Expand Down
2 changes: 1 addition & 1 deletion elements/standard/linkunqueue.hh
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class LinkUnqueue : public Element, public Storage { public:
Timestamp _latency;
// enum { S_TASK, S_TIMER, S_ASLEEP } _state;
bool _back_to_back;
uint32_t _bandwidth;
uint64_t _bandwidth;
Task _task;
Timer _timer;
NotifierSignal _signal;
Expand Down
4 changes: 2 additions & 2 deletions elements/standard/meter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ Meter::push(int, Packet *p)
{
_rate.update(1); // packets, not bytes

unsigned r = _rate.scaled_average();
uint64_t r = _rate.scaled_average();
if (_nmeters < 2) {
int n = (r >= _meter1);
output(n).push(p);
} else {
unsigned *meters = _meters;
uint64_t *meters = _meters;
int nmeters = _nmeters;
for (int i = 0; i < nmeters; i++)
if (r < meters[i]) {
Expand Down
4 changes: 2 additions & 2 deletions elements/standard/ratedsource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ 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;
uint64_t rate = 10;
uint64_t bandwidth = 0;
int limit = -1;
int datasize = -1;
bool active = true, stop = false;
Expand Down
4 changes: 2 additions & 2 deletions elements/standard/ratedunqueue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ 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;
uint64_t tokens;
bool dur_specified, tokens_specified;
const char *burst_size = is_bandwidth ? "BURST_BYTES" : "BURST_SIZE";

Expand Down
2 changes: 1 addition & 1 deletion elements/standard/shaper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Shaper::Shaper()
int
Shaper::configure(Vector<String> &conf, ErrorHandler *errh)
{
uint32_t rate;
uint64_t rate;
Args args(conf, this, errh);
if (is_bandwidth())
args.read_mp("RATE", BandwidthArg(), rate);
Expand Down
8 changes: 4 additions & 4 deletions elements/test/confparsetest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ ConfParseTest::initialize(ErrorHandler *errh)
#endif

BandwidthArg bwarg;
CHECK(bwarg.parse("8", u32) == true && bwarg.status == NumArg::status_unitless && u32 == 8);
CHECK(bwarg.parse("8 baud", u32) == true && bwarg.status == NumArg::status_ok && u32 == 1);
CHECK(bwarg.parse("8Kbps", u32) == true && bwarg.status == NumArg::status_ok && u32 == 1000);
CHECK(bwarg.parse("8KBps", u32) == true && bwarg.status == NumArg::status_ok && u32 == 8000);
CHECK(bwarg.parse("8", u64) == true && bwarg.status == NumArg::status_unitless && u64 == 8);
CHECK(bwarg.parse("8 baud", u64) == true && bwarg.status == NumArg::status_ok && u64 == 1);
CHECK(bwarg.parse("8Kbps", u64) == true && bwarg.status == NumArg::status_ok && u64 == 1000);
CHECK(bwarg.parse("8KBps", u64) == true && bwarg.status == NumArg::status_ok && u64 == 8000);

{
IPAddress a, m;
Expand Down
8 changes: 4 additions & 4 deletions elements/userlevel/jiffieclock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ JiffieClock::initialize(ErrorHandler*) {

void JiffieClock::run_timer(Timer* t) {
Timestamp current_time = Timestamp::now_steady();
int64_t delta = (current_time - last_jiffies_update).msec() / (1000 / CLICK_HZ);
int64_t delta = (current_time - last_jiffies_update).usec() / (1000000 / CLICK_HZ);
if (delta > 0) {
if (unlikely(delta > _minprecision)) {//Accept a little jump from time to time, but not double jump
//We try all the click threads
int nt = (t->home_thread_id() + 1) % master()->nthreads();
if (nt == home_thread_id()) {
click_chatter("Click tasks are too heavy and the jiffie accumulator cannot run at least once every %dmsec, the user jiffie clock is deactivated.",_minprecision);
click_chatter("Click tasks are too heavy and the jiffie accumulator cannot run at least once every %d jiffies, the user jiffie clock is deactivated.",_minprecision);
click_jiffies_fct = &click_timestamp_jiffies;
return;
}
Expand All @@ -78,7 +78,7 @@ void JiffieClock::run_timer(Timer* t) {
jiffies += delta;
last_jiffies_update = current_time;
}
t->schedule_at_steady(last_jiffies_update + Timestamp::make_msec(1000 / CLICK_HZ));
t->schedule_at_steady(last_jiffies_update + Timestamp::make_usec(1000000 / CLICK_HZ));
}

click_jiffies_t JiffieClock::read_jiffies(void* data) {
Expand All @@ -94,7 +94,7 @@ bool JiffieClock::run_task(Task*) {
//TODO : this should be rcu protected
click_jiffies_fct_data = this;
click_jiffies_fct = &read_jiffies;
_timer.schedule_after_msec(1000 / CLICK_HZ);
_timer.schedule_after(Timestamp::make_usec(1000000 / CLICK_HZ));
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion include/click/args.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1376,7 +1376,7 @@ class UnitArg { public:
Handles suffixes such as "Gbps", "k", etc. */
class BandwidthArg : public NumArg { public:
bool parse(const String &str, uint32_t &result, const ArgContext & = blank_args);
bool parse(const String &str, uint64_t &result, const ArgContext & = blank_args);
static String unparse(uint32_t x);
int status;
};
Expand Down
2 changes: 1 addition & 1 deletion include/click/confparse.hh
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ bool cp_seconds(const String& str, double* result);
bool cp_time(const String &str, Timestamp *result, bool allow_negative = false);
bool cp_time(const String& str, struct timeval* result);

bool cp_bandwidth(const String& str, uint32_t* result);
bool cp_bandwidth(const String& str, uint64_t* result);

// network addresses
class IPAddressList;
Expand Down
2 changes: 1 addition & 1 deletion include/click/ewma.hh
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ class RateEWMAXParameters : public FixedEWMAXParameters<STABILITY, SCALE, T, U>
/** @brief A RateEWMAX with stability shift 4 (alpha 1/16), scaling factor 10
* (10 bits of fraction), one rate, and underlying type <code>unsigned</code>
* that measures epochs in jiffies. */
typedef RateEWMAX<RateEWMAXParameters<4, 10> > RateEWMA;
typedef RateEWMAX<RateEWMAXParameters<4, 10, uint64_t, int64_t> > RateEWMA;


template <typename P>
Expand Down
46 changes: 23 additions & 23 deletions include/click/gaprate.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,25 @@ class GapRate { public:

/** @brief Construct a GapRate object with initial rate @a r.
* @param r initial rate (events per second) */
inline GapRate(unsigned r);
inline GapRate(uint64_t r);

/** @brief Return the current rate. */
inline unsigned rate() const;
inline uint64_t rate() const;

/** @brief Set the current rate to @a r.
* @param r desired rate (events per second)
*
* Rates larger than MAX_RATE are reduced to MAX_RATE. Also performs the
* equivalent of a reset() to flush old state. */
inline void set_rate(unsigned r);
inline void set_rate(uint64_t r);

/** @brief Set the current rate to @a r.
* @param r desired rate (events per second)
* @param errh error handler
*
* Acts like set_rate(@a r), except that an warning is reported to @a errh
* if @a r is larger than MAX_RATE. */
void set_rate(unsigned r, ErrorHandler *errh);
void set_rate(uint64_t r, ErrorHandler *errh);


/** @brief Returns whether the user's rate is behind the true rate.
Expand Down Expand Up @@ -97,7 +97,7 @@ class GapRate { public:
*
* @note This may be faster than calling update() @a delta times.
* Furthermore, @a delta can be negative. */
inline void update_with(int delta);
inline void update_with(int64_t delta);

/** @brief Resets the true rate counter.
*
Expand All @@ -106,20 +106,20 @@ class GapRate { public:
inline void reset();


enum { UGAP_SHIFT = 12 };
enum { MAX_RATE = 1000000U << UGAP_SHIFT };
enum { UGAP_SHIFT = 43 };
enum { MAX_RATE = 1000000UL << UGAP_SHIFT };

private:

unsigned _ugap; // (1000000 << UGAP_SHIFT) / _rate
int _sec_count; // number of updates this second so far
uint64_t _ugap; // (1000000 << UGAP_SHIFT) / _rate
int64_t _sec_count; // number of updates this second so far
Timestamp::seconds_type _tv_sec; // current second
unsigned _rate; // desired rate
uint64_t _rate; // desired rate
#if DEBUG_GAPRATE
Timestamp _last;
#endif

inline void initialize_rate(unsigned rate);
inline void initialize_rate(uint64_t rate);

};

Expand All @@ -134,7 +134,7 @@ GapRate::reset()
}

inline void
GapRate::initialize_rate(unsigned r)
GapRate::initialize_rate(uint64_t r)
{
_rate = r;
_ugap = (r == 0 ? MAX_RATE + 1 : MAX_RATE / r);
Expand All @@ -144,15 +144,15 @@ GapRate::initialize_rate(unsigned r)
}

inline void
GapRate::set_rate(unsigned r)
GapRate::set_rate(uint64_t r)
{
if (r > MAX_RATE)
r = MAX_RATE;
if (_rate != r) {
initialize_rate(r);
if (_tv_sec >= 0 && r != 0) {
Timestamp now = Timestamp::now();
_sec_count = (now.usec() << UGAP_SHIFT) / _ugap;
_sec_count = (static_cast<uint64_t>(now.usec()) << UGAP_SHIFT) / _ugap;
}
}
}
Expand All @@ -165,14 +165,14 @@ GapRate::GapRate()
}

inline
GapRate::GapRate(unsigned r)
GapRate::GapRate(uint64_t r)
: _rate(0)
{
initialize_rate(r);
reset();
}

inline unsigned
inline uint64_t
GapRate::rate() const
{
return _rate;
Expand All @@ -182,15 +182,15 @@ inline bool
GapRate::need_update(const Timestamp &now)
{
// this is an approximation of:
// unsigned need = (unsigned) ((now.usec() / 1000000.0) * _rate)
unsigned need = (now.usec() << UGAP_SHIFT) / _ugap;
// uint64_t need = (uint64_t) ((now.usec() / 1000000.0) * _rate)
uint64_t need = (static_cast<uint64_t>(now.usec()) << UGAP_SHIFT) / _ugap;

if (_tv_sec < 0) {
// 27.Feb.2005: often OK to send a packet after reset unless rate is
// 0 -- requested by Bart Braem
// check include/click/gaprate.hh (1.2)
_tv_sec = now.sec();
_sec_count = need + ((now.usec() << UGAP_SHIFT) - (need * _ugap) > _ugap / 2);
_sec_count = need + ((static_cast<uint64_t>(now.usec()) << UGAP_SHIFT) - (need * _ugap) > _ugap / 2);
} else if (now.sec() > _tv_sec) {
_tv_sec = now.sec();
if (_sec_count > 0)
Expand All @@ -200,7 +200,7 @@ GapRate::need_update(const Timestamp &now)
#if DEBUG_GAPRATE
click_chatter("%p{timestamp} -> %u @ %u [%d]", &now, need, _sec_count, (int)need >= _sec_count);
#endif
return ((int)need >= _sec_count);
return ((int64_t)need >= _sec_count);
}

inline void
Expand All @@ -210,7 +210,7 @@ GapRate::update()
}

inline void
GapRate::update_with(int delta)
GapRate::update_with(int64_t delta)
{
_sec_count += delta;
}
Expand All @@ -224,8 +224,8 @@ GapRate::expiry() const
return Timestamp(_tv_sec, 0);
else {
Timestamp::seconds_type sec = _tv_sec;
int count = _sec_count;
if ((unsigned) count >= _rate) {
int64_t count = _sec_count;
if ((uint64_t) count >= _rate) {
sec += count / _rate;
count = count % _rate;
}
Expand Down
4 changes: 2 additions & 2 deletions include/click/glue.hh
Original file line number Diff line number Diff line change
Expand Up @@ -528,10 +528,10 @@ typedef click_jiffies_t (*click_jiffies_fct_t)(void*);
extern click_jiffies_fct_t click_jiffies_fct;
extern void* click_jiffies_fct_data;
# define click_jiffies() (click_jiffies_fct(click_jiffies_fct_data))
# define CLICK_HZ 1000
# define CLICK_HZ 1000000
# else
# define click_jiffies() (click_timestamp_jiffies(0))
# define CLICK_HZ 1000
# define CLICK_HZ 1000000
# endif
# define HAS_LONG_CLICK_JIFFIES_T 1
# define click_jiffies_less(a, b) ((click_jiffies_difference_t) ((a) - (b)) < 0)
Expand Down
12 changes: 6 additions & 6 deletions lib/args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ static const char byte_bandwidth_units[] = "\
static const char byte_bandwidth_prefixes[] = "\
k\103K\103M\106G\111";

static uint32_t
static uint64_t
multiply_factor(uint32_t ix, uint32_t fx, uint32_t factor, int &status)
{
if (factor == 1) {
Expand All @@ -1233,14 +1233,14 @@ multiply_factor(uint32_t ix, uint32_t fx, uint32_t factor, int &status)
if (int32_t(flow) < 0)
++ftoint;
int_multiply(ix, factor, ilow, ihigh);
if (ihigh != 0 || ilow + ftoint < ftoint)
status = NumArg::status_range;
return ilow + ftoint;
/* if (ihigh != 0 || ilow + ftoint < ftoint)
status = NumArg::status_range; */
return ((uint64_t) ihigh << 32) + ilow + ftoint;
}
}

bool
BandwidthArg::parse(const String &str, uint32_t &result, const ArgContext &args)
BandwidthArg::parse(const String &str, uint64_t &result, const ArgContext &args)
{
int power, factor;
const char *unit_end = UnitArg(byte_bandwidth_units, byte_bandwidth_prefixes).parse(str.begin(), str.end(), power, factor);
Expand All @@ -1258,7 +1258,7 @@ BandwidthArg::parse(const String &str, uint32_t &result, const ArgContext &args)
ix = multiply_factor(ix, fx, factor, status);
if (status == status_range) {
args.error("out of range");
result = 0xFFFFFFFFU;
result = UINT64_MAX;
return false;
} else {
if (unit_end == str.end() && ix)
Expand Down
Loading

0 comments on commit d81fded

Please sign in to comment.