diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-04-21 11:37:56 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-04-21 11:37:56 +0200 |
commit | 300bb8d62d412eccb1537cbdaf27b8264fa6fc19 (patch) | |
tree | e5c097394c1ccfe605e945d263198100e367426c /src/util/bandwidth.c | |
parent | 32485c3b58983ada1943b3fa27eac3b0cff2a9da (diff) | |
download | gnunet-300bb8d62d412eccb1537cbdaf27b8264fa6fc19.tar.gz gnunet-300bb8d62d412eccb1537cbdaf27b8264fa6fc19.zip |
fix quota out calculation, even if it may go away
Diffstat (limited to 'src/util/bandwidth.c')
-rw-r--r-- | src/util/bandwidth.c | 161 |
1 files changed, 90 insertions, 71 deletions
diff --git a/src/util/bandwidth.c b/src/util/bandwidth.c index 5cf1297c7..bdac43b77 100644 --- a/src/util/bandwidth.c +++ b/src/util/bandwidth.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -27,7 +27,7 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | 28 | ||
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-bandwidth", __VA_ARGS__) | 30 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-bandwidth", __VA_ARGS__) |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Create a new bandwidth value. | 33 | * Create a new bandwidth value. |
@@ -56,10 +56,8 @@ struct GNUNET_BANDWIDTH_Value32NBO | |||
56 | GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1, | 56 | GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1, |
57 | struct GNUNET_BANDWIDTH_Value32NBO b2) | 57 | struct GNUNET_BANDWIDTH_Value32NBO b2) |
58 | { | 58 | { |
59 | return | 59 | return GNUNET_BANDWIDTH_value_init ( |
60 | GNUNET_BANDWIDTH_value_init (GNUNET_MIN | 60 | GNUNET_MIN (ntohl (b1.value__), ntohl (b2.value__))); |
61 | (ntohl (b1.value__), | ||
62 | ntohl (b2.value__))); | ||
63 | } | 61 | } |
64 | 62 | ||
65 | 63 | ||
@@ -74,10 +72,23 @@ struct GNUNET_BANDWIDTH_Value32NBO | |||
74 | GNUNET_BANDWIDTH_value_max (struct GNUNET_BANDWIDTH_Value32NBO b1, | 72 | GNUNET_BANDWIDTH_value_max (struct GNUNET_BANDWIDTH_Value32NBO b1, |
75 | struct GNUNET_BANDWIDTH_Value32NBO b2) | 73 | struct GNUNET_BANDWIDTH_Value32NBO b2) |
76 | { | 74 | { |
77 | return | 75 | return GNUNET_BANDWIDTH_value_init ( |
78 | GNUNET_BANDWIDTH_value_init (GNUNET_MAX | 76 | GNUNET_MAX (ntohl (b1.value__), ntohl (b2.value__))); |
79 | (ntohl (b1.value__), | 77 | } |
80 | ntohl (b2.value__))); | 78 | |
79 | |||
80 | /** | ||
81 | * Compute the SUM of two bandwidth values. | ||
82 | * | ||
83 | * @param b1 first value | ||
84 | * @param b2 second value | ||
85 | * @return the sum of b1 and b2 | ||
86 | */ | ||
87 | struct GNUNET_BANDWIDTH_Value32NBO | ||
88 | GNUNET_BANDWIDTH_value_sum (struct GNUNET_BANDWIDTH_Value32NBO b1, | ||
89 | struct GNUNET_BANDWIDTH_Value32NBO b2) | ||
90 | { | ||
91 | return GNUNET_BANDWIDTH_value_init (ntohl (b1.value__) + ntohl (b2.value__)); | ||
81 | } | 92 | } |
82 | 93 | ||
83 | 94 | ||
@@ -90,15 +101,17 @@ GNUNET_BANDWIDTH_value_max (struct GNUNET_BANDWIDTH_Value32NBO b1, | |||
90 | * @return number of bytes available at bps until deadline | 101 | * @return number of bytes available at bps until deadline |
91 | */ | 102 | */ |
92 | uint64_t | 103 | uint64_t |
93 | GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO bps, | 104 | GNUNET_BANDWIDTH_value_get_available_until ( |
94 | struct GNUNET_TIME_Relative deadline) | 105 | struct GNUNET_BANDWIDTH_Value32NBO bps, |
106 | struct GNUNET_TIME_Relative deadline) | ||
95 | { | 107 | { |
96 | uint64_t b; | 108 | uint64_t b; |
97 | 109 | ||
98 | b = ntohl (bps.value__); | 110 | b = ntohl (bps.value__); |
99 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 111 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
100 | "Bandwidth has %llu bytes available until deadline in %s\n", | 112 | "Bandwidth has %llu bytes available until deadline in %s\n", |
101 | (unsigned long long) ((b * deadline.rel_value_us + 500000LL) / 1000000LL), | 113 | (unsigned long long) ((b * deadline.rel_value_us + 500000LL) / |
114 | 1000000LL), | ||
102 | GNUNET_STRINGS_relative_time_to_string (deadline, GNUNET_YES)); | 115 | GNUNET_STRINGS_relative_time_to_string (deadline, GNUNET_YES)); |
103 | return (b * deadline.rel_value_us + 500000LL) / 1000000LL; | 116 | return (b * deadline.rel_value_us + 500000LL) / 1000000LL; |
104 | } | 117 | } |
@@ -149,7 +162,7 @@ excess_trigger (void *cls) | |||
149 | if (NULL != av->excess_cb) | 162 | if (NULL != av->excess_cb) |
150 | { | 163 | { |
151 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
152 | "Notifying application about excess bandwidth\n"); | 165 | "Notifying application about excess bandwidth\n"); |
153 | av->excess_cb (av->excess_cb_cls); | 166 | av->excess_cb (av->excess_cb_cls); |
154 | } | 167 | } |
155 | } | 168 | } |
@@ -174,8 +187,9 @@ update_excess (struct GNUNET_BANDWIDTH_Tracker *av) | |||
174 | now = GNUNET_TIME_absolute_get (); | 187 | now = GNUNET_TIME_absolute_get (); |
175 | delta_time = now.abs_value_us - av->last_update__.abs_value_us; | 188 | delta_time = now.abs_value_us - av->last_update__.abs_value_us; |
176 | delta_avail = | 189 | delta_avail = |
177 | (delta_time * ((unsigned long long) av->available_bytes_per_s__) + | 190 | (delta_time * ((unsigned long long) av->available_bytes_per_s__) + |
178 | 500000LL) / 1000000LL; | 191 | 500000LL) / |
192 | 1000000LL; | ||
179 | current_consumption = av->consumption_since_last_update__ - delta_avail; | 193 | current_consumption = av->consumption_since_last_update__ - delta_avail; |
180 | if (current_consumption > av->consumption_since_last_update__) | 194 | if (current_consumption > av->consumption_since_last_update__) |
181 | { | 195 | { |
@@ -203,21 +217,20 @@ update_excess (struct GNUNET_BANDWIDTH_Tracker *av) | |||
203 | } | 217 | } |
204 | else | 218 | else |
205 | { | 219 | { |
206 | double factor = 1.0 * left_bytes / (double) av->available_bytes_per_s__; | 220 | double factor = 1.0 * left_bytes / (double) av->available_bytes_per_s__; |
207 | delay = GNUNET_TIME_relative_saturating_multiply (GNUNET_TIME_UNIT_SECONDS, | 221 | delay = |
208 | (unsigned long long) factor); | 222 | GNUNET_TIME_relative_saturating_multiply (GNUNET_TIME_UNIT_SECONDS, |
223 | (unsigned long long) factor); | ||
209 | } | 224 | } |
210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 225 | GNUNET_log ( |
211 | "At %llu bps it will take us %s for %lld bytes to reach excess threshold\n", | 226 | GNUNET_ERROR_TYPE_DEBUG, |
212 | (unsigned long long) av->available_bytes_per_s__, | 227 | "At %llu bps it will take us %s for %lld bytes to reach excess threshold\n", |
213 | GNUNET_STRINGS_relative_time_to_string (delay, | 228 | (unsigned long long) av->available_bytes_per_s__, |
214 | GNUNET_NO), | 229 | GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_NO), |
215 | (long long) left_bytes); | 230 | (long long) left_bytes); |
216 | if (NULL != av->excess_task) | 231 | if (NULL != av->excess_task) |
217 | GNUNET_SCHEDULER_cancel (av->excess_task); | 232 | GNUNET_SCHEDULER_cancel (av->excess_task); |
218 | av->excess_task = GNUNET_SCHEDULER_add_delayed (delay, | 233 | av->excess_task = GNUNET_SCHEDULER_add_delayed (delay, &excess_trigger, av); |
219 | &excess_trigger, | ||
220 | av); | ||
221 | } | 234 | } |
222 | 235 | ||
223 | 236 | ||
@@ -243,13 +256,14 @@ update_excess (struct GNUNET_BANDWIDTH_Tracker *av) | |||
243 | * @param excess_cb_cls closure for @a excess_cb | 256 | * @param excess_cb_cls closure for @a excess_cb |
244 | */ | 257 | */ |
245 | void | 258 | void |
246 | GNUNET_BANDWIDTH_tracker_init2 (struct GNUNET_BANDWIDTH_Tracker *av, | 259 | GNUNET_BANDWIDTH_tracker_init2 ( |
247 | GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, | 260 | struct GNUNET_BANDWIDTH_Tracker *av, |
248 | void *update_cb_cls, | 261 | GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, |
249 | struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, | 262 | void *update_cb_cls, |
250 | uint32_t max_carry_s, | 263 | struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, |
251 | GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb, | 264 | uint32_t max_carry_s, |
252 | void *excess_cb_cls) | 265 | GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb, |
266 | void *excess_cb_cls) | ||
253 | { | 267 | { |
254 | av->update_cb = update_cb; | 268 | av->update_cb = update_cb; |
255 | av->update_cb_cls = update_cb_cls; | 269 | av->update_cb_cls = update_cb_cls; |
@@ -285,17 +299,20 @@ GNUNET_BANDWIDTH_tracker_init2 (struct GNUNET_BANDWIDTH_Tracker *av, | |||
285 | * may accumulate before it expires | 299 | * may accumulate before it expires |
286 | */ | 300 | */ |
287 | void | 301 | void |
288 | GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av, | 302 | GNUNET_BANDWIDTH_tracker_init ( |
289 | GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, | 303 | struct GNUNET_BANDWIDTH_Tracker *av, |
290 | void *update_cb_cls, | 304 | GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, |
291 | struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, | 305 | void *update_cb_cls, |
292 | uint32_t max_carry_s) | 306 | struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, |
307 | uint32_t max_carry_s) | ||
293 | { | 308 | { |
294 | GNUNET_BANDWIDTH_tracker_init2 (av, update_cb, | 309 | GNUNET_BANDWIDTH_tracker_init2 (av, |
310 | update_cb, | ||
295 | update_cb_cls, | 311 | update_cb_cls, |
296 | bytes_per_second_limit, | 312 | bytes_per_second_limit, |
297 | max_carry_s, | 313 | max_carry_s, |
298 | NULL, NULL); | 314 | NULL, |
315 | NULL); | ||
299 | } | 316 | } |
300 | 317 | ||
301 | 318 | ||
@@ -335,36 +352,36 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av) | |||
335 | now = GNUNET_TIME_absolute_get (); | 352 | now = GNUNET_TIME_absolute_get (); |
336 | delta_time = now.abs_value_us - av->last_update__.abs_value_us; | 353 | delta_time = now.abs_value_us - av->last_update__.abs_value_us; |
337 | delta_avail = | 354 | delta_avail = |
338 | (delta_time * ((unsigned long long) av->available_bytes_per_s__) + | 355 | (delta_time * ((unsigned long long) av->available_bytes_per_s__) + |
339 | 500000LL) / 1000000LL; | 356 | 500000LL) / |
357 | 1000000LL; | ||
340 | av->consumption_since_last_update__ -= delta_avail; | 358 | av->consumption_since_last_update__ -= delta_avail; |
341 | av->last_update__ = now; | 359 | av->last_update__ = now; |
342 | if (av->consumption_since_last_update__ < 0) | 360 | if (av->consumption_since_last_update__ < 0) |
343 | { | 361 | { |
344 | left_bytes = - av->consumption_since_last_update__; | 362 | left_bytes = -av->consumption_since_last_update__; |
345 | max_carry = ((unsigned long long) av->available_bytes_per_s__) * | 363 | max_carry = |
346 | av->max_carry_s__; | 364 | ((unsigned long long) av->available_bytes_per_s__) * av->max_carry_s__; |
347 | if (max_carry < GNUNET_MAX_MESSAGE_SIZE) | 365 | if (max_carry < GNUNET_MAX_MESSAGE_SIZE) |
348 | max_carry = GNUNET_MAX_MESSAGE_SIZE; | 366 | max_carry = GNUNET_MAX_MESSAGE_SIZE; |
349 | if (max_carry > INT64_MAX) | 367 | if (max_carry > INT64_MAX) |
350 | max_carry = INT64_MAX; | 368 | max_carry = INT64_MAX; |
351 | if (max_carry > left_bytes) | 369 | if (max_carry > left_bytes) |
352 | av->consumption_since_last_update__ = - left_bytes; | 370 | av->consumption_since_last_update__ = -left_bytes; |
353 | else | 371 | else |
354 | av->consumption_since_last_update__ = - max_carry; | 372 | av->consumption_since_last_update__ = -max_carry; |
355 | } | 373 | } |
356 | #if !defined(GNUNET_CULL_LOGGING) | 374 | #if ! defined(GNUNET_CULL_LOGGING) |
357 | { | 375 | { |
358 | struct GNUNET_TIME_Relative delta; | 376 | struct GNUNET_TIME_Relative delta; |
359 | 377 | ||
360 | delta.rel_value_us = delta_time; | 378 | delta.rel_value_us = delta_time; |
361 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 379 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
362 | "Tracker %p updated, consumption at %lld at %u Bps, last update was %s ago\n", | 380 | "Tracker %p updated, consumption at %lld at %u Bps, last update was %s ago\n", |
363 | av, | 381 | av, |
364 | (long long) av->consumption_since_last_update__, | 382 | (long long) av->consumption_since_last_update__, |
365 | (unsigned int) av->available_bytes_per_s__, | 383 | (unsigned int) av->available_bytes_per_s__, |
366 | GNUNET_STRINGS_relative_time_to_string (delta, | 384 | GNUNET_STRINGS_relative_time_to_string (delta, GNUNET_YES)); |
367 | GNUNET_YES)); | ||
368 | } | 385 | } |
369 | #endif | 386 | #endif |
370 | } | 387 | } |
@@ -407,7 +424,7 @@ GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av, | |||
407 | { | 424 | { |
408 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 425 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
409 | "Tracker %p consumption %llu bytes above limit\n", | 426 | "Tracker %p consumption %llu bytes above limit\n", |
410 | av, | 427 | av, |
411 | (unsigned long long) av->consumption_since_last_update__); | 428 | (unsigned long long) av->consumption_since_last_update__); |
412 | return GNUNET_YES; | 429 | return GNUNET_YES; |
413 | } | 430 | } |
@@ -446,8 +463,7 @@ GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av, | |||
446 | 463 | ||
447 | if (0 == av->available_bytes_per_s__) | 464 | if (0 == av->available_bytes_per_s__) |
448 | { | 465 | { |
449 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 466 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p delay is infinity\n", av); |
450 | "Tracker %p delay is infinity\n", av); | ||
451 | return GNUNET_TIME_UNIT_FOREVER_REL; | 467 | return GNUNET_TIME_UNIT_FOREVER_REL; |
452 | } | 468 | } |
453 | update_tracker (av); | 469 | update_tracker (av); |
@@ -455,13 +471,13 @@ GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av, | |||
455 | if (bytes_needed <= 0) | 471 | if (bytes_needed <= 0) |
456 | { | 472 | { |
457 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 473 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
458 | "Tracker %p delay for %u bytes is zero\n", av, | 474 | "Tracker %p delay for %u bytes is zero\n", |
475 | av, | ||
459 | (unsigned int) size); | 476 | (unsigned int) size); |
460 | return GNUNET_TIME_UNIT_ZERO; | 477 | return GNUNET_TIME_UNIT_ZERO; |
461 | } | 478 | } |
462 | ret.rel_value_us = | 479 | ret.rel_value_us = (1000LL * 1000LL * bytes_needed) / |
463 | (1000LL * 1000LL * bytes_needed) / | 480 | (unsigned long long) av->available_bytes_per_s__; |
464 | (unsigned long long) av->available_bytes_per_s__; | ||
465 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 481 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
466 | "Tracker %p delay for %u bytes is %s\n", | 482 | "Tracker %p delay for %u bytes is %s\n", |
467 | av, | 483 | av, |
@@ -488,12 +504,13 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av) | |||
488 | update_tracker (av); | 504 | update_tracker (av); |
489 | bps = GNUNET_BANDWIDTH_value_init (av->available_bytes_per_s__); | 505 | bps = GNUNET_BANDWIDTH_value_init (av->available_bytes_per_s__); |
490 | avail = | 506 | avail = |
491 | GNUNET_BANDWIDTH_value_get_available_until (bps, | 507 | GNUNET_BANDWIDTH_value_get_available_until (bps, |
492 | GNUNET_TIME_absolute_get_duration | 508 | GNUNET_TIME_absolute_get_duration ( |
493 | (av->last_update__)); | 509 | av->last_update__)); |
494 | used = av->consumption_since_last_update__; | 510 | used = av->consumption_since_last_update__; |
495 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 511 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
496 | "Tracker %p available bandwidth is %lld bytes\n", av, | 512 | "Tracker %p available bandwidth is %lld bytes\n", |
513 | av, | ||
497 | (long long) (int64_t) (avail - used)); | 514 | (long long) (int64_t) (avail - used)); |
498 | return (int64_t) (avail - used); | 515 | return (int64_t) (avail - used); |
499 | } | 516 | } |
@@ -506,15 +523,17 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av) | |||
506 | * @param bytes_per_second_limit new limit to assume | 523 | * @param bytes_per_second_limit new limit to assume |
507 | */ | 524 | */ |
508 | void | 525 | void |
509 | GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av, | 526 | GNUNET_BANDWIDTH_tracker_update_quota ( |
510 | struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit) | 527 | struct GNUNET_BANDWIDTH_Tracker *av, |
528 | struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit) | ||
511 | { | 529 | { |
512 | uint32_t old_limit; | 530 | uint32_t old_limit; |
513 | uint32_t new_limit; | 531 | uint32_t new_limit; |
514 | 532 | ||
515 | new_limit = ntohl (bytes_per_second_limit.value__); | 533 | new_limit = ntohl (bytes_per_second_limit.value__); |
516 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 534 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
517 | "Tracker %p bandwidth changed to %u Bps\n", av, | 535 | "Tracker %p bandwidth changed to %u Bps\n", |
536 | av, | ||
518 | (unsigned int) new_limit); | 537 | (unsigned int) new_limit); |
519 | update_tracker (av); | 538 | update_tracker (av); |
520 | old_limit = av->available_bytes_per_s__; | 539 | old_limit = av->available_bytes_per_s__; |
@@ -522,7 +541,7 @@ GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av, | |||
522 | if (NULL != av->update_cb) | 541 | if (NULL != av->update_cb) |
523 | av->update_cb (av->update_cb_cls); | 542 | av->update_cb (av->update_cb_cls); |
524 | if (old_limit > new_limit) | 543 | if (old_limit > new_limit) |
525 | update_tracker (av); /* maximum excess might be less now */ | 544 | update_tracker (av); /* maximum excess might be less now */ |
526 | update_excess (av); | 545 | update_excess (av); |
527 | } | 546 | } |
528 | 547 | ||