diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-10-22 12:36:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-10-22 12:36:41 +0000 |
commit | ddd69826be47a1956c6972c2cfcadfa7902b8639 (patch) | |
tree | dd632db2ba084a1a83b0ef57189333f2bbd354a6 /src/fragmentation | |
parent | 582f893b55d9536864b59ad3ccb1dfeb43ff31b7 (diff) | |
download | gnunet-ddd69826be47a1956c6972c2cfcadfa7902b8639.tar.gz gnunet-ddd69826be47a1956c6972c2cfcadfa7902b8639.zip |
-trying to fix fragmentation / udp performance, not working yet
Diffstat (limited to 'src/fragmentation')
-rw-r--r-- | src/fragmentation/fragmentation.c | 91 | ||||
-rw-r--r-- | src/fragmentation/test_fragmentation.c | 8 |
2 files changed, 75 insertions, 24 deletions
diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c index 4749f5378..19f7ff175 100644 --- a/src/fragmentation/fragmentation.c +++ b/src/fragmentation/fragmentation.c | |||
@@ -52,7 +52,12 @@ struct GNUNET_FRAGMENT_Context | |||
52 | /** | 52 | /** |
53 | * Current expected delay for ACKs. | 53 | * Current expected delay for ACKs. |
54 | */ | 54 | */ |
55 | struct GNUNET_TIME_Relative delay; | 55 | struct GNUNET_TIME_Relative ack_delay; |
56 | |||
57 | /** | ||
58 | * Current expected delay between messages. | ||
59 | */ | ||
60 | struct GNUNET_TIME_Relative msg_delay; | ||
56 | 61 | ||
57 | /** | 62 | /** |
58 | * Next allowed transmission time. | 63 | * Next allowed transmission time. |
@@ -181,11 +186,11 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
181 | return; | 186 | return; |
182 | } | 187 | } |
183 | fc->next_transmission = (fc->next_transmission + 1) % 64; | 188 | fc->next_transmission = (fc->next_transmission + 1) % 64; |
184 | wrap |= (fc->next_transmission == 0); | 189 | wrap |= (0 == fc->next_transmission); |
185 | while (0 == (fc->acks & (1LL << fc->next_transmission))) | 190 | while (0 == (fc->acks & (1LL << fc->next_transmission))) |
186 | { | 191 | { |
187 | fc->next_transmission = (fc->next_transmission + 1) % 64; | 192 | fc->next_transmission = (fc->next_transmission + 1) % 64; |
188 | wrap |= (fc->next_transmission == 0); | 193 | wrap |= (0 == fc->next_transmission); |
189 | } | 194 | } |
190 | 195 | ||
191 | /* assemble fragmentation message */ | 196 | /* assemble fragmentation message */ |
@@ -217,16 +222,17 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
217 | delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize); | 222 | delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize); |
218 | else | 223 | else |
219 | delay = GNUNET_TIME_UNIT_ZERO; | 224 | delay = GNUNET_TIME_UNIT_ZERO; |
225 | delay = GNUNET_TIME_relative_max (delay, | ||
226 | fc->msg_delay); | ||
220 | if (wrap) | 227 | if (wrap) |
221 | { | 228 | { |
222 | /* full round transmitted wait 2x delay for ACK before going again */ | 229 | /* full round transmitted wait 2x delay for ACK before going again */ |
223 | fc->num_rounds++; | 230 | fc->num_rounds++; |
224 | delay = | 231 | delay = GNUNET_TIME_relative_multiply (delay, 2); |
225 | GNUNET_TIME_relative_max (GNUNET_TIME_relative_multiply (delay, 2), | 232 | fc->msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay, |
226 | GNUNET_TIME_relative_multiply (fc->delay, | 233 | 2 + (size / (fc->mtu - sizeof (struct FragmentHeader)))); |
227 | fc->num_rounds)); | ||
228 | /* never use zero, need some time for ACK always */ | 234 | /* never use zero, need some time for ACK always */ |
229 | delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay); | 235 | delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay); |
230 | fc->wack = GNUNET_YES; | 236 | fc->wack = GNUNET_YES; |
231 | fc->last_round = GNUNET_TIME_absolute_get (); | 237 | fc->last_round = GNUNET_TIME_absolute_get (); |
232 | GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1, | 238 | GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1, |
@@ -250,7 +256,9 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
250 | * @param stats statistics context | 256 | * @param stats statistics context |
251 | * @param mtu the maximum message size for each fragment | 257 | * @param mtu the maximum message size for each fragment |
252 | * @param tracker bandwidth tracker to use for flow control (can be NULL) | 258 | * @param tracker bandwidth tracker to use for flow control (can be NULL) |
253 | * @param delay expected delay between fragment transmission | 259 | * @param msg_delay initial delay to insert between fragment transmissions |
260 | * based on previous messages | ||
261 | * @param ack_delay expected delay between fragment transmission | ||
254 | * and ACK based on previous messages | 262 | * and ACK based on previous messages |
255 | * @param msg the message to fragment | 263 | * @param msg the message to fragment |
256 | * @param proc function to call for each fragment to transmit | 264 | * @param proc function to call for each fragment to transmit |
@@ -261,7 +269,8 @@ struct GNUNET_FRAGMENT_Context * | |||
261 | GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | 269 | GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, |
262 | uint16_t mtu, | 270 | uint16_t mtu, |
263 | struct GNUNET_BANDWIDTH_Tracker *tracker, | 271 | struct GNUNET_BANDWIDTH_Tracker *tracker, |
264 | struct GNUNET_TIME_Relative delay, | 272 | struct GNUNET_TIME_Relative msg_delay, |
273 | struct GNUNET_TIME_Relative ack_delay, | ||
265 | const struct GNUNET_MessageHeader *msg, | 274 | const struct GNUNET_MessageHeader *msg, |
266 | GNUNET_FRAGMENT_MessageProcessor proc, | 275 | GNUNET_FRAGMENT_MessageProcessor proc, |
267 | void *proc_cls) | 276 | void *proc_cls) |
@@ -280,7 +289,8 @@ GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | |||
280 | fc->stats = stats; | 289 | fc->stats = stats; |
281 | fc->mtu = mtu; | 290 | fc->mtu = mtu; |
282 | fc->tracker = tracker; | 291 | fc->tracker = tracker; |
283 | fc->delay = delay; | 292 | fc->ack_delay = ack_delay; |
293 | fc->msg_delay = msg_delay; | ||
284 | fc->msg = (const struct GNUNET_MessageHeader *) &fc[1]; | 294 | fc->msg = (const struct GNUNET_MessageHeader *) &fc[1]; |
285 | fc->proc = proc; | 295 | fc->proc = proc; |
286 | fc->proc_cls = proc_cls; | 296 | fc->proc_cls = proc_cls; |
@@ -339,7 +349,11 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc, | |||
339 | const struct FragmentAcknowledgement *fa; | 349 | const struct FragmentAcknowledgement *fa; |
340 | uint64_t abits; | 350 | uint64_t abits; |
341 | struct GNUNET_TIME_Relative ndelay; | 351 | struct GNUNET_TIME_Relative ndelay; |
352 | unsigned int ack_cnt; | ||
353 | unsigned int snd_cnt; | ||
354 | unsigned int i; | ||
342 | 355 | ||
356 | fprintf (stderr, "Got ACK!\n"); | ||
343 | if (sizeof (struct FragmentAcknowledgement) != ntohs (msg->size)) | 357 | if (sizeof (struct FragmentAcknowledgement) != ntohs (msg->size)) |
344 | { | 358 | { |
345 | GNUNET_break_op (0); | 359 | GNUNET_break_op (0); |
@@ -355,9 +369,40 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc, | |||
355 | /* normal ACK, can update running average of delay... */ | 369 | /* normal ACK, can update running average of delay... */ |
356 | fc->wack = GNUNET_NO; | 370 | fc->wack = GNUNET_NO; |
357 | ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round); | 371 | ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round); |
358 | fc->delay.rel_value = | 372 | fc->ack_delay.rel_value = |
359 | (ndelay.rel_value / fc->num_transmissions + 3 * fc->delay.rel_value) / 4; | 373 | (ndelay.rel_value / fc->num_transmissions + 3 * fc->ack_delay.rel_value) / 4; |
360 | fc->num_transmissions = 0; | 374 | fc->num_transmissions = 0; |
375 | /* calculate ratio msg sent vs. msg acked */ | ||
376 | ack_cnt = 0; | ||
377 | snd_cnt = 0; | ||
378 | for (i=0;i<64;i++) | ||
379 | { | ||
380 | if (1 == (fc->acks_mask & (1 << i))) | ||
381 | { | ||
382 | snd_cnt++; | ||
383 | if (0 == (abits & (1 << i))) | ||
384 | ack_cnt++; | ||
385 | } | ||
386 | } | ||
387 | if (0 == ack_cnt) | ||
388 | { | ||
389 | /* complete loss */ | ||
390 | fc->msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay, | ||
391 | snd_cnt); | ||
392 | } | ||
393 | else if (snd_cnt > ack_cnt) | ||
394 | { | ||
395 | /* some loss, slow down proportionally */ | ||
396 | fc->msg_delay.rel_value = ((fc->msg_delay.rel_value * ack_cnt) / snd_cnt); | ||
397 | } | ||
398 | else if (0 < fc->msg_delay.rel_value) | ||
399 | { | ||
400 | fc->msg_delay.rel_value--; /* try a bit faster */ | ||
401 | } | ||
402 | fc->msg_delay = GNUNET_TIME_relative_max (fc->msg_delay, | ||
403 | GNUNET_TIME_UNIT_SECONDS); | ||
404 | fprintf (stderr, "New msg delay: %llu\n", | ||
405 | (unsigned long long )fc->msg_delay.rel_value); | ||
361 | } | 406 | } |
362 | GNUNET_STATISTICS_update (fc->stats, | 407 | GNUNET_STATISTICS_update (fc->stats, |
363 | _("# fragment acknowledgements received"), 1, | 408 | _("# fragment acknowledgements received"), 1, |
@@ -406,19 +451,23 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc, | |||
406 | * resources). | 451 | * resources). |
407 | * | 452 | * |
408 | * @param fc fragmentation context | 453 | * @param fc fragmentation context |
409 | * @return average delay between transmission and ACK for the | 454 | * @param msg_delay where to store average delay between individual message transmissions the |
410 | * last message, FOREVER if the message was not fully transmitted | 455 | * last message (OUT only) |
456 | * @param ack_delay where to store average delay between transmission and ACK for the | ||
457 | * last message, set to FOREVER if the message was not fully transmitted (OUT only) | ||
411 | */ | 458 | */ |
412 | struct GNUNET_TIME_Relative | 459 | void |
413 | GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc) | 460 | GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc, |
461 | struct GNUNET_TIME_Relative *msg_delay, | ||
462 | struct GNUNET_TIME_Relative *ack_delay) | ||
414 | { | 463 | { |
415 | struct GNUNET_TIME_Relative ret; | ||
416 | |||
417 | if (fc->task != GNUNET_SCHEDULER_NO_TASK) | 464 | if (fc->task != GNUNET_SCHEDULER_NO_TASK) |
418 | GNUNET_SCHEDULER_cancel (fc->task); | 465 | GNUNET_SCHEDULER_cancel (fc->task); |
419 | ret = fc->delay; | 466 | if (NULL != ack_delay) |
467 | *ack_delay = fc->ack_delay; | ||
468 | if (NULL != msg_delay) | ||
469 | *msg_delay = fc->msg_delay; | ||
420 | GNUNET_free (fc); | 470 | GNUNET_free (fc); |
421 | return ret; | ||
422 | } | 471 | } |
423 | 472 | ||
424 | 473 | ||
diff --git a/src/fragmentation/test_fragmentation.c b/src/fragmentation/test_fragmentation.c index 0381a8dd0..ecbcdddab 100644 --- a/src/fragmentation/test_fragmentation.c +++ b/src/fragmentation/test_fragmentation.c | |||
@@ -77,7 +77,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
77 | { | 77 | { |
78 | if (frags[i] == NULL) | 78 | if (frags[i] == NULL) |
79 | continue; | 79 | continue; |
80 | GNUNET_FRAGMENT_context_destroy (frags[i]); | 80 | GNUNET_FRAGMENT_context_destroy (frags[i], NULL, NULL); |
81 | frags[i] = NULL; | 81 | frags[i] = NULL; |
82 | } | 82 | } |
83 | } | 83 | } |
@@ -134,7 +134,7 @@ proc_acks (void *cls, uint32_t msg_id, const struct GNUNET_MessageHeader *hdr) | |||
134 | #if DETAILS | 134 | #if DETAILS |
135 | FPRINTF (stderr, "%s", "@"); /* good ACK */ | 135 | FPRINTF (stderr, "%s", "@"); /* good ACK */ |
136 | #endif | 136 | #endif |
137 | GNUNET_FRAGMENT_context_destroy (frags[i]); | 137 | GNUNET_FRAGMENT_context_destroy (frags[i], NULL, NULL); |
138 | frags[i] = NULL; | 138 | frags[i] = NULL; |
139 | acks++; | 139 | acks++; |
140 | return; | 140 | return; |
@@ -215,7 +215,9 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
215 | htons (sizeof (struct GNUNET_MessageHeader) + (17 * i) % (32 * 1024)); | 215 | htons (sizeof (struct GNUNET_MessageHeader) + (17 * i) % (32 * 1024)); |
216 | frags[i] = GNUNET_FRAGMENT_context_create (NULL /* no stats */ , | 216 | frags[i] = GNUNET_FRAGMENT_context_create (NULL /* no stats */ , |
217 | MTU, &trackers[i], | 217 | MTU, &trackers[i], |
218 | GNUNET_TIME_UNIT_SECONDS, msg, | 218 | GNUNET_TIME_UNIT_MILLISECONDS, |
219 | GNUNET_TIME_UNIT_SECONDS, | ||
220 | msg, | ||
219 | &proc_frac, &frags[i]); | 221 | &proc_frac, &frags[i]); |
220 | } | 222 | } |
221 | } | 223 | } |