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.c182
1 files changed, 89 insertions, 93 deletions
diff --git a/src/util/bandwidth.c b/src/util/bandwidth.c
index 6f25abfd5..d138ffba1 100644
--- a/src/util/bandwidth.c
+++ b/src/util/bandwidth.c
@@ -42,8 +42,8 @@ GNUNET_BANDWIDTH_value_init (uint32_t bytes_per_second)
42 42
43#if DEBUG_BANDWIDTH 43#if DEBUG_BANDWIDTH
44 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 44 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
45 "Initializing bandwidth of %u Bps\n", 45 "Initializing bandwidth of %u Bps\n",
46 (unsigned int) bytes_per_second); 46 (unsigned int) bytes_per_second);
47#endif 47#endif
48 ret.value__ = htonl (bytes_per_second); 48 ret.value__ = htonl (bytes_per_second);
49 return ret; 49 return ret;
@@ -59,10 +59,10 @@ GNUNET_BANDWIDTH_value_init (uint32_t bytes_per_second)
59 */ 59 */
60struct GNUNET_BANDWIDTH_Value32NBO 60struct GNUNET_BANDWIDTH_Value32NBO
61GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1, 61GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1,
62 struct GNUNET_BANDWIDTH_Value32NBO b2) 62 struct GNUNET_BANDWIDTH_Value32NBO b2)
63{ 63{
64 return GNUNET_BANDWIDTH_value_init (GNUNET_MIN (ntohl (b1.value__), 64 return GNUNET_BANDWIDTH_value_init (GNUNET_MIN (ntohl (b1.value__),
65 ntohl (b2.value__))); 65 ntohl (b2.value__)));
66} 66}
67 67
68 68
@@ -74,18 +74,20 @@ GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1,
74 * @param deadline when is the deadline 74 * @param deadline when is the deadline
75 * @return number of bytes available at bps until deadline 75 * @return number of bytes available at bps until deadline
76 */ 76 */
77uint64_t 77uint64_t
78GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO bps, 78GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO
79 struct GNUNET_TIME_Relative deadline) 79 bps,
80 struct GNUNET_TIME_Relative
81 deadline)
80{ 82{
81 uint64_t b; 83 uint64_t b;
82 84
83 b = ntohl (bps.value__); 85 b = ntohl (bps.value__);
84#if DEBUG_BANDWIDTH 86#if DEBUG_BANDWIDTH
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 87 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Bandwidth has %llu bytes available until deadline in %llums\n", 88 "Bandwidth has %llu bytes available until deadline in %llums\n",
87 (unsigned long long) ((b * deadline.rel_value + 500LL) / 1000LL), 89 (unsigned long long) ((b * deadline.rel_value + 500LL) / 1000LL),
88 deadline.rel_value); 90 deadline.rel_value);
89#endif 91#endif
90 return (b * deadline.rel_value + 500LL) / 1000LL; 92 return (b * deadline.rel_value + 500LL) / 1000LL;
91} 93}
@@ -101,26 +103,25 @@ GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO b
101 */ 103 */
102struct GNUNET_TIME_Relative 104struct GNUNET_TIME_Relative
103GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps, 105GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps,
104 uint64_t size) 106 uint64_t size)
105{ 107{
106 uint64_t b; 108 uint64_t b;
107 struct GNUNET_TIME_Relative ret; 109 struct GNUNET_TIME_Relative ret;
108 110
109 b = ntohl (bps.value__); 111 b = ntohl (bps.value__);
110 if (b == 0) 112 if (b == 0)
111 { 113 {
112#if DEBUG_BANDWIDTH 114#if DEBUG_BANDWIDTH
113 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
114 "Bandwidth suggests delay of infinity (zero bandwidth)\n"); 116 "Bandwidth suggests delay of infinity (zero bandwidth)\n");
115#endif 117#endif
116 return GNUNET_TIME_UNIT_FOREVER_REL; 118 return GNUNET_TIME_UNIT_FOREVER_REL;
117 } 119 }
118 ret.rel_value = size * 1000LL / b; 120 ret.rel_value = size * 1000LL / b;
119#if DEBUG_BANDWIDTH 121#if DEBUG_BANDWIDTH
120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
121 "Bandwidth suggests delay of %llu ms for %llu bytes of traffic\n", 123 "Bandwidth suggests delay of %llu ms for %llu bytes of traffic\n",
122 (unsigned long long) ret.rel_value, 124 (unsigned long long) ret.rel_value, (unsigned long long) size);
123 (unsigned long long) size);
124#endif 125#endif
125 return ret; 126 return ret;
126} 127}
@@ -142,8 +143,8 @@ GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps,
142 */ 143 */
143void 144void
144GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av, 145GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av,
145 struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, 146 struct GNUNET_BANDWIDTH_Value32NBO
146 uint32_t max_carry_s) 147 bytes_per_second_limit, uint32_t max_carry_s)
147{ 148{
148 av->consumption_since_last_update__ = 0; 149 av->consumption_since_last_update__ = 0;
149 av->last_update__ = GNUNET_TIME_absolute_get (); 150 av->last_update__ = GNUNET_TIME_absolute_get ();
@@ -151,10 +152,10 @@ GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av,
151 av->max_carry_s__ = max_carry_s; 152 av->max_carry_s__ = max_carry_s;
152#if DEBUG_BANDWIDTH 153#if DEBUG_BANDWIDTH
153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
154 "Tracker %p initialized with %u Bps and max carry %u\n", 155 "Tracker %p initialized with %u Bps and max carry %u\n",
155 av, 156 av,
156 (unsigned int) av->available_bytes_per_s__, 157 (unsigned int) av->available_bytes_per_s__,
157 (unsigned int) max_carry_s); 158 (unsigned int) max_carry_s);
158#endif 159#endif
159} 160}
160 161
@@ -176,26 +177,28 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
176 177
177 now = GNUNET_TIME_absolute_get (); 178 now = GNUNET_TIME_absolute_get ();
178 delta_time = now.abs_value - av->last_update__.abs_value; 179 delta_time = now.abs_value - av->last_update__.abs_value;
179 delta_avail = (delta_time * ((unsigned long long) av->available_bytes_per_s__) + 500LL) / 1000LL; 180 delta_avail =
181 (delta_time * ((unsigned long long) av->available_bytes_per_s__) +
182 500LL) / 1000LL;
180 av->consumption_since_last_update__ -= delta_avail; 183 av->consumption_since_last_update__ -= delta_avail;
181 av->last_update__ = now; 184 av->last_update__ = now;
182 if (av->consumption_since_last_update__ < 0) 185 if (av->consumption_since_last_update__ < 0)
183 { 186 {
184 left_bytes = - av->consumption_since_last_update__; 187 left_bytes = -av->consumption_since_last_update__;
185 max_carry = av->available_bytes_per_s__ * av->max_carry_s__; 188 max_carry = av->available_bytes_per_s__ * av->max_carry_s__;
186 if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE) 189 if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE)
187 max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE; 190 max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE;
188 if (max_carry > left_bytes) 191 if (max_carry > left_bytes)
189 av->consumption_since_last_update__ = -left_bytes; 192 av->consumption_since_last_update__ = -left_bytes;
190 else 193 else
191 av->consumption_since_last_update__ = -max_carry; 194 av->consumption_since_last_update__ = -max_carry;
192 } 195 }
193#if DEBUG_BANDWIDTH 196#if DEBUG_BANDWIDTH
194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
195 "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",
196 av, 199 av,
197 (unsigned int) av->available_bytes_per_s__, 200 (unsigned int) av->available_bytes_per_s__,
198 (unsigned long long) delta_time); 201 (unsigned long long) delta_time);
199#endif 202#endif
200 203
201} 204}
@@ -214,41 +217,38 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
214 */ 217 */
215int 218int
216GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av, 219GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
217 ssize_t size) 220 ssize_t size)
218{ 221{
219 int64_t nc; 222 int64_t nc;
220 223
221#if DEBUG_BANDWIDTH 224#if DEBUG_BANDWIDTH
222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
223 "Tracker %p consumes %d bytes\n", 226 "Tracker %p consumes %d bytes\n", av, (int) size);
224 av,
225 (int) size);
226#endif 227#endif
227 if (size > 0) 228 if (size > 0)
229 {
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)
228 { 239 {
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)
238 {
239#if DEBUG_BANDWIDTH 240#if DEBUG_BANDWIDTH
240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
241 "Tracker %p consumption %llu bytes above limit\n", 242 "Tracker %p consumption %llu bytes above limit\n",
242 av, 243 av, (unsigned long long) av->consumption_since_last_update__);
243 (unsigned long long) av->consumption_since_last_update__);
244#endif 244#endif
245 return GNUNET_YES; 245 return GNUNET_YES;
246 }
247 } 246 }
247 }
248 else 248 else
249 { 249 {
250 av->consumption_since_last_update__ += size; 250 av->consumption_since_last_update__ += size;
251 } 251 }
252 return GNUNET_NO; 252 return GNUNET_NO;
253} 253}
254 254
@@ -264,39 +264,35 @@ GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
264 */ 264 */
265struct GNUNET_TIME_Relative 265struct GNUNET_TIME_Relative
266GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av, 266GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av,
267 size_t size) 267 size_t size)
268{ 268{
269 struct GNUNET_TIME_Relative ret; 269 struct GNUNET_TIME_Relative ret;
270 int64_t bytes_needed; 270 int64_t bytes_needed;
271 271
272 if (av->available_bytes_per_s__ == 0) 272 if (av->available_bytes_per_s__ == 0)
273 { 273 {
274#if DEBUG_BANDWIDTH 274#if DEBUG_BANDWIDTH
275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p delay is infinity\n", av);
276 "Tracker %p delay is infinity\n",
277 av);
278#endif 276#endif
279 return GNUNET_TIME_UNIT_FOREVER_REL; 277 return GNUNET_TIME_UNIT_FOREVER_REL;
280 } 278 }
281 update_tracker (av); 279 update_tracker (av);
282 bytes_needed = size + av->consumption_since_last_update__; 280 bytes_needed = size + av->consumption_since_last_update__;
283 if (bytes_needed <= 0) 281 if (bytes_needed <= 0)
284 { 282 {
285#if DEBUG_BANDWIDTH 283#if DEBUG_BANDWIDTH
286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
287 "Tracker %p delay for %u bytes is zero\n", 285 "Tracker %p delay for %u bytes is zero\n",
288 av, 286 av, (unsigned int) size);
289 (unsigned int) size);
290#endif 287#endif
291 return GNUNET_TIME_UNIT_ZERO; 288 return GNUNET_TIME_UNIT_ZERO;
292 } 289 }
293 ret.rel_value = 1000LL * bytes_needed / (unsigned long long) av->available_bytes_per_s__; 290 ret.rel_value =
291 1000LL * bytes_needed / (unsigned long long) av->available_bytes_per_s__;
294#if DEBUG_BANDWIDTH 292#if DEBUG_BANDWIDTH
295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 293 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
296 "Tracker %p delay for %u bytes is %llu ms\n", 294 "Tracker %p delay for %u bytes is %llu ms\n",
297 av, 295 av, (unsigned int) size, (unsigned long long) ret.rel_value);
298 (unsigned int) size,
299 (unsigned long long) ret.rel_value);
300#endif 296#endif
301 return ret; 297 return ret;
302} 298}
@@ -309,8 +305,8 @@ GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av,
309 * @param av tracker to query 305 * @param av tracker to query
310 * @return number of bytes available for consumption right now 306 * @return number of bytes available for consumption right now
311 */ 307 */
312int64_t 308int64_t
313GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av) 309GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker * av)
314{ 310{
315 struct GNUNET_BANDWIDTH_Value32NBO bps; 311 struct GNUNET_BANDWIDTH_Value32NBO bps;
316 uint64_t avail; 312 uint64_t avail;
@@ -319,13 +315,13 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av)
319 update_tracker (av); 315 update_tracker (av);
320 bps = GNUNET_BANDWIDTH_value_init (av->available_bytes_per_s__); 316 bps = GNUNET_BANDWIDTH_value_init (av->available_bytes_per_s__);
321 avail = GNUNET_BANDWIDTH_value_get_available_until (bps, 317 avail = GNUNET_BANDWIDTH_value_get_available_until (bps,
322 GNUNET_TIME_absolute_get_duration (av->last_update__)); 318 GNUNET_TIME_absolute_get_duration
319 (av->last_update__));
323 used = av->consumption_since_last_update__; 320 used = av->consumption_since_last_update__;
324#if DEBUG_BANDWIDTH 321#if DEBUG_BANDWIDTH
325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
326 "Tracker %p available bandwidth is %lld bytes\n", 323 "Tracker %p available bandwidth is %lld bytes\n",
327 av, 324 av, (long long) (int64_t) (avail - used));
328 (long long) (int64_t) (avail - used));
329#endif 325#endif
330 return (int64_t) (avail - used); 326 return (int64_t) (avail - used);
331} 327}
@@ -339,7 +335,8 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av)
339 */ 335 */
340void 336void
341GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av, 337GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av,
342 struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit) 338 struct GNUNET_BANDWIDTH_Value32NBO
339 bytes_per_second_limit)
343{ 340{
344 uint32_t old_limit; 341 uint32_t old_limit;
345 uint32_t new_limit; 342 uint32_t new_limit;
@@ -347,15 +344,14 @@ GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av,
347 new_limit = ntohl (bytes_per_second_limit.value__); 344 new_limit = ntohl (bytes_per_second_limit.value__);
348#if DEBUG_BANDWIDTH 345#if DEBUG_BANDWIDTH
349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
350 "Tracker %p bandwidth changed to %u Bps\n", 347 "Tracker %p bandwidth changed to %u Bps\n",
351 av, 348 av, (unsigned int) new_limit);
352 (unsigned int) new_limit);
353#endif 349#endif
354 update_tracker (av); 350 update_tracker (av);
355 old_limit = av->available_bytes_per_s__; 351 old_limit = av->available_bytes_per_s__;
356 av->available_bytes_per_s__ = new_limit; 352 av->available_bytes_per_s__ = new_limit;
357 if (old_limit > new_limit) 353 if (old_limit > new_limit)
358 update_tracker (av); /* maximum excess might be less now */ 354 update_tracker (av); /* maximum excess might be less now */
359} 355}
360 356
361 357