aboutsummaryrefslogtreecommitdiff
path: root/src/util/bandwidth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/bandwidth.c')
-rw-r--r--src/util/bandwidth.c141
1 files changed, 69 insertions, 72 deletions
diff --git a/src/util/bandwidth.c b/src/util/bandwidth.c
index a736b7607..0920362f5 100644
--- a/src/util/bandwidth.c
+++ b/src/util/bandwidth.c
@@ -60,11 +60,11 @@ GNUNET_BANDWIDTH_value_init (uint32_t bytes_per_second)
60 */ 60 */
61struct GNUNET_BANDWIDTH_Value32NBO 61struct GNUNET_BANDWIDTH_Value32NBO
62GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1, 62GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1,
63 struct GNUNET_BANDWIDTH_Value32NBO b2) 63 struct GNUNET_BANDWIDTH_Value32NBO b2)
64{ 64{
65 return 65 return
66 GNUNET_BANDWIDTH_value_init (GNUNET_MIN 66 GNUNET_BANDWIDTH_value_init (GNUNET_MIN
67 (ntohl (b1.value__), ntohl (b2.value__))); 67 (ntohl (b1.value__), ntohl (b2.value__)));
68} 68}
69 69
70 70
@@ -78,9 +78,9 @@ GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1,
78 */ 78 */
79uint64_t 79uint64_t
80GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO 80GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO
81 bps, 81 bps,
82 struct GNUNET_TIME_Relative 82 struct GNUNET_TIME_Relative
83 deadline) 83 deadline)
84{ 84{
85 uint64_t b; 85 uint64_t b;
86 86
@@ -105,20 +105,20 @@ GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO
105 */ 105 */
106struct GNUNET_TIME_Relative 106struct GNUNET_TIME_Relative
107GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps, 107GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps,
108 uint64_t size) 108 uint64_t size)
109{ 109{
110 uint64_t b; 110 uint64_t b;
111 struct GNUNET_TIME_Relative ret; 111 struct GNUNET_TIME_Relative ret;
112 112
113 b = ntohl (bps.value__); 113 b = ntohl (bps.value__);
114 if (b == 0) 114 if (b == 0)
115 { 115 {
116#if DEBUG_BANDWIDTH 116#if DEBUG_BANDWIDTH
117 LOG (GNUNET_ERROR_TYPE_DEBUG, 117 LOG (GNUNET_ERROR_TYPE_DEBUG,
118 "Bandwidth suggests delay of infinity (zero bandwidth)\n"); 118 "Bandwidth suggests delay of infinity (zero bandwidth)\n");
119#endif 119#endif
120 return GNUNET_TIME_UNIT_FOREVER_REL; 120 return GNUNET_TIME_UNIT_FOREVER_REL;
121 } 121 }
122 ret.rel_value = size * 1000LL / b; 122 ret.rel_value = size * 1000LL / b;
123#if DEBUG_BANDWIDTH 123#if DEBUG_BANDWIDTH
124 LOG (GNUNET_ERROR_TYPE_DEBUG, 124 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -145,8 +145,8 @@ GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps,
145 */ 145 */
146void 146void
147GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av, 147GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av,
148 struct GNUNET_BANDWIDTH_Value32NBO 148 struct GNUNET_BANDWIDTH_Value32NBO
149 bytes_per_second_limit, uint32_t max_carry_s) 149 bytes_per_second_limit, uint32_t max_carry_s)
150{ 150{
151 av->consumption_since_last_update__ = 0; 151 av->consumption_since_last_update__ = 0;
152 av->last_update__ = GNUNET_TIME_absolute_get (); 152 av->last_update__ = GNUNET_TIME_absolute_get ();
@@ -155,8 +155,7 @@ GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av,
155#if DEBUG_BANDWIDTH 155#if DEBUG_BANDWIDTH
156 LOG (GNUNET_ERROR_TYPE_DEBUG, 156 LOG (GNUNET_ERROR_TYPE_DEBUG,
157 "Tracker %p initialized with %u Bps and max carry %u\n", av, 157 "Tracker %p initialized with %u Bps and max carry %u\n", av,
158 (unsigned int) av->available_bytes_per_s__, 158 (unsigned int) av->available_bytes_per_s__, (unsigned int) max_carry_s);
159 (unsigned int) max_carry_s);
160#endif 159#endif
161} 160}
162 161
@@ -179,25 +178,25 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
179 now = GNUNET_TIME_absolute_get (); 178 now = GNUNET_TIME_absolute_get ();
180 delta_time = now.abs_value - av->last_update__.abs_value; 179 delta_time = now.abs_value - av->last_update__.abs_value;
181 delta_avail = 180 delta_avail =
182 (delta_time * ((unsigned long long) av->available_bytes_per_s__) + 181 (delta_time * ((unsigned long long) av->available_bytes_per_s__) +
183 500LL) / 1000LL; 182 500LL) / 1000LL;
184 av->consumption_since_last_update__ -= delta_avail; 183 av->consumption_since_last_update__ -= delta_avail;
185 av->last_update__ = now; 184 av->last_update__ = now;
186 if (av->consumption_since_last_update__ < 0) 185 if (av->consumption_since_last_update__ < 0)
187 { 186 {
188 left_bytes = -av->consumption_since_last_update__; 187 left_bytes = -av->consumption_since_last_update__;
189 max_carry = av->available_bytes_per_s__ * av->max_carry_s__; 188 max_carry = av->available_bytes_per_s__ * av->max_carry_s__;
190 if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE) 189 if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE)
191 max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE; 190 max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE;
192 if (max_carry > left_bytes) 191 if (max_carry > left_bytes)
193 av->consumption_since_last_update__ = -left_bytes; 192 av->consumption_since_last_update__ = -left_bytes;
194 else 193 else
195 av->consumption_since_last_update__ = -max_carry; 194 av->consumption_since_last_update__ = -max_carry;
196 } 195 }
197#if DEBUG_BANDWIDTH 196#if DEBUG_BANDWIDTH
198 LOG (GNUNET_ERROR_TYPE_DEBUG, 197 LOG (GNUNET_ERROR_TYPE_DEBUG,
199 "Tracker %p updated, have %u Bps, last update was %llu ms ago\n", 198 "Tracker %p updated, have %u Bps, last update was %llu ms ago\n", av,
200 av, (unsigned int) av->available_bytes_per_s__, 199 (unsigned int) av->available_bytes_per_s__,
201 (unsigned long long) delta_time); 200 (unsigned long long) delta_time);
202#endif 201#endif
203 202
@@ -217,7 +216,7 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
217 */ 216 */
218int 217int
219GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av, 218GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
220 ssize_t size) 219 ssize_t size)
221{ 220{
222 int64_t nc; 221 int64_t nc;
223 222
@@ -226,29 +225,29 @@ GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
226 (int) size); 225 (int) size);
227#endif 226#endif
228 if (size > 0) 227 if (size > 0)
228 {
229 nc = av->consumption_since_last_update__ + size;
230 if (nc < av->consumption_since_last_update__)
231 {
232 GNUNET_break (0);
233 return GNUNET_SYSERR;
234 }
235 av->consumption_since_last_update__ = nc;
236 update_tracker (av);
237 if (av->consumption_since_last_update__ > 0)
229 { 238 {
230 nc = av->consumption_since_last_update__ + size;
231 if (nc < av->consumption_since_last_update__)
232 {
233 GNUNET_break (0);
234 return GNUNET_SYSERR;
235 }
236 av->consumption_since_last_update__ = nc;
237 update_tracker (av);
238 if (av->consumption_since_last_update__ > 0)
239 {
240#if DEBUG_BANDWIDTH 239#if DEBUG_BANDWIDTH
241 LOG (GNUNET_ERROR_TYPE_DEBUG, 240 LOG (GNUNET_ERROR_TYPE_DEBUG,
242 "Tracker %p consumption %llu bytes above limit\n", av, 241 "Tracker %p consumption %llu bytes above limit\n", av,
243 (unsigned long long) av->consumption_since_last_update__); 242 (unsigned long long) av->consumption_since_last_update__);
244#endif 243#endif
245 return GNUNET_YES; 244 return GNUNET_YES;
246 }
247 } 245 }
246 }
248 else 247 else
249 { 248 {
250 av->consumption_since_last_update__ += size; 249 av->consumption_since_last_update__ += size;
251 } 250 }
252 return GNUNET_NO; 251 return GNUNET_NO;
253} 252}
254 253
@@ -264,35 +263,34 @@ GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
264 */ 263 */
265struct GNUNET_TIME_Relative 264struct GNUNET_TIME_Relative
266GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av, 265GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av,
267 size_t size) 266 size_t size)
268{ 267{
269 struct GNUNET_TIME_Relative ret; 268 struct GNUNET_TIME_Relative ret;
270 int64_t bytes_needed; 269 int64_t bytes_needed;
271 270
272 if (av->available_bytes_per_s__ == 0) 271 if (av->available_bytes_per_s__ == 0)
273 { 272 {
274#if DEBUG_BANDWIDTH 273#if DEBUG_BANDWIDTH
275 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p delay is infinity\n", av); 274 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p delay is infinity\n", av);
276#endif 275#endif
277 return GNUNET_TIME_UNIT_FOREVER_REL; 276 return GNUNET_TIME_UNIT_FOREVER_REL;
278 } 277 }
279 update_tracker (av); 278 update_tracker (av);
280 bytes_needed = size + av->consumption_since_last_update__; 279 bytes_needed = size + av->consumption_since_last_update__;
281 if (bytes_needed <= 0) 280 if (bytes_needed <= 0)
282 { 281 {
283#if DEBUG_BANDWIDTH 282#if DEBUG_BANDWIDTH
284 LOG (GNUNET_ERROR_TYPE_DEBUG, 283 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p delay for %u bytes is zero\n", av,
285 "Tracker %p delay for %u bytes is zero\n", av, 284 (unsigned int) size);
286 (unsigned int) size);
287#endif 285#endif
288 return GNUNET_TIME_UNIT_ZERO; 286 return GNUNET_TIME_UNIT_ZERO;
289 } 287 }
290 ret.rel_value = 288 ret.rel_value =
291 (1000LL * bytes_needed) / (unsigned long long) av->available_bytes_per_s__; 289 (1000LL * bytes_needed) /
290 (unsigned long long) av->available_bytes_per_s__;
292#if DEBUG_BANDWIDTH 291#if DEBUG_BANDWIDTH
293 LOG (GNUNET_ERROR_TYPE_DEBUG, 292 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p delay for %u bytes is %llu ms\n",
294 "Tracker %p delay for %u bytes is %llu ms\n", av, 293 av, (unsigned int) size, (unsigned long long) ret.rel_value);
295 (unsigned int) size, (unsigned long long) ret.rel_value);
296#endif 294#endif
297 return ret; 295 return ret;
298} 296}
@@ -315,9 +313,9 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker * av)
315 update_tracker (av); 313 update_tracker (av);
316 bps = GNUNET_BANDWIDTH_value_init (av->available_bytes_per_s__); 314 bps = GNUNET_BANDWIDTH_value_init (av->available_bytes_per_s__);
317 avail = 315 avail =
318 GNUNET_BANDWIDTH_value_get_available_until (bps, 316 GNUNET_BANDWIDTH_value_get_available_until (bps,
319 GNUNET_TIME_absolute_get_duration 317 GNUNET_TIME_absolute_get_duration
320 (av->last_update__)); 318 (av->last_update__));
321 used = av->consumption_since_last_update__; 319 used = av->consumption_since_last_update__;
322#if DEBUG_BANDWIDTH 320#if DEBUG_BANDWIDTH
323 LOG (GNUNET_ERROR_TYPE_DEBUG, 321 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -336,23 +334,22 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker * av)
336 */ 334 */
337void 335void
338GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av, 336GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av,
339 struct GNUNET_BANDWIDTH_Value32NBO 337 struct GNUNET_BANDWIDTH_Value32NBO
340 bytes_per_second_limit) 338 bytes_per_second_limit)
341{ 339{
342 uint32_t old_limit; 340 uint32_t old_limit;
343 uint32_t new_limit; 341 uint32_t new_limit;
344 342
345 new_limit = ntohl (bytes_per_second_limit.value__); 343 new_limit = ntohl (bytes_per_second_limit.value__);
346#if DEBUG_BANDWIDTH 344#if DEBUG_BANDWIDTH
347 LOG (GNUNET_ERROR_TYPE_DEBUG, 345 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p bandwidth changed to %u Bps\n", av,
348 "Tracker %p bandwidth changed to %u Bps\n", av,
349 (unsigned int) new_limit); 346 (unsigned int) new_limit);
350#endif 347#endif
351 update_tracker (av); 348 update_tracker (av);
352 old_limit = av->available_bytes_per_s__; 349 old_limit = av->available_bytes_per_s__;
353 av->available_bytes_per_s__ = new_limit; 350 av->available_bytes_per_s__ = new_limit;
354 if (old_limit > new_limit) 351 if (old_limit > new_limit)
355 update_tracker (av); /* maximum excess might be less now */ 352 update_tracker (av); /* maximum excess might be less now */
356} 353}
357 354
358 355