Click
Loading...
Searching...
No Matches
gaprate.hh
Go to the documentation of this file.
1// -*- c-basic-offset: 4; related-file-name: "../../lib/gaprate.cc" -*-
2#ifndef CLICK_GAPRATE_HH
3#define CLICK_GAPRATE_HH
4#include <click/timestamp.hh>
5CLICK_DECLS
6class ErrorHandler;
7
45class GapRate { public:
46
48 inline GapRate();
49
52 inline GapRate(uint64_t r);
53
55 inline uint64_t rate() const;
56
62 inline void set_rate(uint64_t r);
63
70 void set_rate(uint64_t r, ErrorHandler *errh);
71
72
78 inline bool need_update(const Timestamp &ts);
79
88 inline Timestamp expiry() const;
89
93 inline void update();
94
100 inline void update_with(int64_t delta);
101
106 inline void reset();
107
108
109 enum { UGAP_SHIFT = 43 };
110 enum { MAX_RATE = 1000000ULL << UGAP_SHIFT };
111
112 private:
113
114 uint64_t _ugap; // (1000000 << UGAP_SHIFT) / _rate
115 int64_t _sec_count; // number of updates this second so far
116 Timestamp::seconds_type _tv_sec; // current second
117 uint64_t _rate; // desired rate
118#if DEBUG_GAPRATE
119 Timestamp _last;
120#endif
121
122 inline void initialize_rate(uint64_t rate);
123
124};
125
127inline void
129{
130 _tv_sec = -1;
131#if DEBUG_GAPRATE
132 _last.set_sec(0);
133#endif
134}
135
136inline void
137GapRate::initialize_rate(uint64_t r)
138{
139 _rate = r;
140 _ugap = (r == 0 ? MAX_RATE + 1 : MAX_RATE / r);
141#if DEBUG_GAPRATE
142 click_chatter("ugap: %u", _ugap);
143#endif
144}
145
146inline void
148{
149 if (r > MAX_RATE)
150 r = MAX_RATE;
151 if (_rate != r) {
152 initialize_rate(r);
153 if (_tv_sec >= 0 && r != 0) {
155 _sec_count = (static_cast<uint64_t>(now.usec()) << UGAP_SHIFT) / _ugap;
156 }
157 }
158}
159
160inline
162{
163 initialize_rate(0);
164 reset();
165}
166
167inline
169 : _rate(0)
170{
171 initialize_rate(r);
172 reset();
173}
174
175inline uint64_t
177{
178 return _rate;
179}
180
181inline bool
183{
184 // this is an approximation of:
185 // uint64_t need = (uint64_t) ((now.usec() / 1000000.0) * _rate)
186 uint64_t need = (static_cast<uint64_t>(now.usec()) << UGAP_SHIFT) / _ugap;
187
188 if (_tv_sec < 0) {
189 // 27.Feb.2005: often OK to send a packet after reset unless rate is
190 // 0 -- requested by Bart Braem
191 // check include/click/gaprate.hh (1.2)
192 _tv_sec = now.sec();
193 _sec_count = need + ((static_cast<uint64_t>(now.usec()) << UGAP_SHIFT) - (need * _ugap) > _ugap / 2);
194 } else if (now.sec() > _tv_sec) {
195 _tv_sec = now.sec();
196 if (_sec_count > 0)
197 _sec_count -= _rate;
198 }
199
200#if DEBUG_GAPRATE
201 click_chatter("%p{timestamp} -> %u @ %u [%d]", &now, need, _sec_count, (int)need >= _sec_count);
202#endif
203 return ((int64_t)need >= _sec_count);
204}
205
206inline void
208{
209 _sec_count++;
210}
211
212inline void
214{
215 _sec_count += delta;
216}
217
218inline Timestamp
220{
221 if (_tv_sec < 0 || _rate == 0)
222 return Timestamp();
223 else if (_sec_count < 0)
224 return Timestamp(_tv_sec, 0);
225 else {
226 Timestamp::seconds_type sec = _tv_sec;
227 int64_t count = _sec_count;
228 if ((uint64_t) count >= _rate) {
229 sec += count / _rate;
230 count = count % _rate;
231 }
232
233 // uint32_t usec = (int) (count * 1000000.0 / _rate)
234 uint32_t usec = (count * _ugap) >> UGAP_SHIFT;
235 return Timestamp::make_usec(sec, usec);
236 }
237}
238
239CLICK_ENDDECLS
240#endif
Error reporting class.
Definition error.hh:90
A helper class for implementing a uniform rate.
Definition gaprate.hh:45
void update_with(int64_t delta)
Increment the user event counter by delta.
Definition gaprate.hh:213
void reset()
Resets the true rate counter.
Definition gaprate.hh:128
Timestamp expiry() const
Returns a time when the user's rate will be behind the true rate.
Definition gaprate.hh:219
void set_rate(uint64_t r)
Set the current rate to r.
Definition gaprate.hh:147
GapRate()
Construct a GapRate object with initial rate 0.
Definition gaprate.hh:161
uint64_t rate() const
Return the current rate.
Definition gaprate.hh:176
bool need_update(const Timestamp &ts)
Returns whether the user's rate is behind the true rate.
Definition gaprate.hh:182
void update()
Increment the user event counter.
Definition gaprate.hh:207
Represents a moment or interval in time.
Definition timestamp.hh:125
static Timestamp now()
Return the current system time.
Definition timestamp.hh:958
static Timestamp make_usec(seconds_type sec, uint32_t usec)
Return a timestamp representing sec seconds plus usec microseconds.
Definition timestamp.hh:349
int32_t seconds_type
Type represents a number of seconds.
Definition timestamp.hh:128
uint32_t usec() const
Return this timestamp's subseconds component, converted to microseconds.
Definition timestamp.hh:1109
seconds_type sec() const
Return this timestamp's seconds component.
Definition timestamp.hh:1075
The Timestamp class represents a moment or interval in time.