aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-05-16 14:59:28 +0000
committerChristian Grothoff <christian@grothoff.org>2012-05-16 14:59:28 +0000
commit8fcb9162a53613e4df429136b2d8567f5ddd0a91 (patch)
tree4a52db1925eec7a3dfffa4486608c6b1c364a26b /src
parent7137a0aaac2e218ad3d0bf2ce6fcb69c9da088f7 (diff)
downloadgnunet-8fcb9162a53613e4df429136b2d8567f5ddd0a91.tar.gz
gnunet-8fcb9162a53613e4df429136b2d8567f5ddd0a91.zip
-improving fragmentation performance
Diffstat (limited to 'src')
-rw-r--r--src/fragmentation/defragmentation.c19
-rw-r--r--src/fragmentation/fragmentation.c29
2 files changed, 40 insertions, 8 deletions
diff --git a/src/fragmentation/defragmentation.c b/src/fragmentation/defragmentation.c
index 061277c41..cc6875a9b 100644
--- a/src/fragmentation/defragmentation.c
+++ b/src/fragmentation/defragmentation.c
@@ -420,7 +420,9 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
420 unsigned int bc; 420 unsigned int bc;
421 unsigned int b; 421 unsigned int b;
422 unsigned int n; 422 unsigned int n;
423 unsigned int num_fragments;
423 int duplicate; 424 int duplicate;
425 int last;
424 426
425 if (ntohs (msg->size) < sizeof (struct FragmentHeader)) 427 if (ntohs (msg->size) < sizeof (struct FragmentHeader))
426 { 428 {
@@ -452,6 +454,12 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
452 return GNUNET_SYSERR; 454 return GNUNET_SYSERR;
453 } 455 }
454 GNUNET_STATISTICS_update (dc->stats, _("# fragments received"), 1, GNUNET_NO); 456 GNUNET_STATISTICS_update (dc->stats, _("# fragments received"), 1, GNUNET_NO);
457 num_fragments = (ntohs (msg->size) + dc->mtu - sizeof (struct FragmentHeader)-1) / (dc->mtu - sizeof (struct FragmentHeader));
458 last = 0;
459 for (mc = dc->head; NULL != mc; mc = mc->next)
460 if (mc->fragment_id > fid)
461 last++;
462
455 mc = dc->head; 463 mc = dc->head;
456 while ((NULL != mc) && (fid != mc->fragment_id)) 464 while ((NULL != mc) && (fid != mc->fragment_id))
457 mc = mc->next; 465 mc = mc->next;
@@ -530,10 +538,19 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
530 } 538 }
531 /* send ACK */ 539 /* send ACK */
532 if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1) 540 if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1)
541 {
533 dc->latency = estimate_latency (mc); 542 dc->latency = estimate_latency (mc);
543 GNUNET_STATISTICS_set (dc->stats, _("# Defragmentation latency estimate (ms)"),
544 dc->latency.rel_value,
545 GNUNET_NO);
546 }
534 delay = GNUNET_TIME_relative_multiply (dc->latency, bc + 1); 547 delay = GNUNET_TIME_relative_multiply (dc->latency, bc + 1);
535 if ((0 == mc->bits) || (GNUNET_YES == duplicate)) /* message complete or duplicate, ACK now! */ 548 if ( (last + fid == num_fragments) ||
549 (0 == mc->bits) ||
550 (GNUNET_YES == duplicate))
536 { 551 {
552 /* message complete or duplicate or last missing fragment in
553 linear sequence; ACK now! */
537 delay = GNUNET_TIME_UNIT_ZERO; 554 delay = GNUNET_TIME_UNIT_ZERO;
538 } 555 }
539 if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) 556 if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task)
diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c
index ee867b04d..9c9fea251 100644
--- a/src/fragmentation/fragmentation.c
+++ b/src/fragmentation/fragmentation.c
@@ -111,6 +111,11 @@ struct GNUNET_FRAGMENT_Context
111 unsigned int num_rounds; 111 unsigned int num_rounds;
112 112
113 /** 113 /**
114 * How many transmission have we completed in this round?
115 */
116 unsigned int num_transmissions;
117
118 /**
114 * GNUNET_YES if we called 'proc' and are now waiting for 'GNUNET_FRAGMENT_transmission_done' 119 * GNUNET_YES if we called 'proc' and are now waiting for 'GNUNET_FRAGMENT_transmission_done'
115 */ 120 */
116 int8_t proc_busy; 121 int8_t proc_busy;
@@ -151,13 +156,12 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
151 GNUNET_assert (GNUNET_NO == fc->proc_busy); 156 GNUNET_assert (GNUNET_NO == fc->proc_busy);
152 if (0 == fc->acks) 157 if (0 == fc->acks)
153 return; /* all done */ 158 return; /* all done */
154
155 /* calculate delay */ 159 /* calculate delay */
156 wrap = 0; 160 wrap = 0;
157 while (0 == (fc->acks & (1LL << fc->next_transmission))) 161 while (0 == (fc->acks & (1LL << fc->next_transmission)))
158 { 162 {
159 fc->next_transmission = (fc->next_transmission + 1) % 64; 163 fc->next_transmission = (fc->next_transmission + 1) % 64;
160 wrap |= (fc->next_transmission == 0); 164 wrap |= (0 == fc->next_transmission);
161 } 165 }
162 bit = fc->next_transmission; 166 bit = fc->next_transmission;
163 size = ntohs (fc->msg->size); 167 size = ntohs (fc->msg->size);
@@ -167,7 +171,7 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
167 sizeof (struct FragmentHeader); 171 sizeof (struct FragmentHeader);
168 else 172 else
169 fsize = fc->mtu; 173 fsize = fc->mtu;
170 if (fc->tracker != NULL) 174 if (NULL != fc->tracker)
171 delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize); 175 delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize);
172 else 176 else
173 delay = GNUNET_TIME_UNIT_ZERO; 177 delay = GNUNET_TIME_UNIT_ZERO;
@@ -223,11 +227,18 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
223 fc->num_rounds)); 227 fc->num_rounds));
224 /* never use zero, need some time for ACK always */ 228 /* never use zero, need some time for ACK always */
225 delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay); 229 delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay);
226 fc->last_round = GNUNET_TIME_absolute_get ();
227 fc->wack = GNUNET_YES; 230 fc->wack = GNUNET_YES;
231 fc->last_round = GNUNET_TIME_absolute_get ();
232 GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1,
233 GNUNET_NO);
228 } 234 }
235 GNUNET_STATISTICS_set (fc->stats,
236 _("# next delay for fragment transmission"),
237 delay.rel_value,
238 GNUNET_NO);
229 fc->proc_busy = GNUNET_YES; 239 fc->proc_busy = GNUNET_YES;
230 fc->delay_until = GNUNET_TIME_relative_to_absolute (delay); 240 fc->delay_until = GNUNET_TIME_relative_to_absolute (delay);
241 fc->num_transmissions++;
231 fc->proc (fc->proc_cls, &fh->header); 242 fc->proc (fc->proc_cls, &fh->header);
232} 243}
233 244
@@ -262,7 +273,9 @@ GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
262 struct GNUNET_FRAGMENT_Context *fc; 273 struct GNUNET_FRAGMENT_Context *fc;
263 size_t size; 274 size_t size;
264 uint64_t bits; 275 uint64_t bits;
265 276
277 GNUNET_STATISTICS_set (stats, _("# expected ACK delay for fragments"),
278 delay.rel_value, GNUNET_NO);
266 GNUNET_STATISTICS_update (stats, _("# messages fragmented"), 1, GNUNET_NO); 279 GNUNET_STATISTICS_update (stats, _("# messages fragmented"), 1, GNUNET_NO);
267 GNUNET_assert (mtu >= 1024 + sizeof (struct FragmentHeader)); 280 GNUNET_assert (mtu >= 1024 + sizeof (struct FragmentHeader));
268 size = ntohs (msg->size); 281 size = ntohs (msg->size);
@@ -342,13 +355,15 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
342 if (ntohl (fa->fragment_id) != fc->fragment_id) 355 if (ntohl (fa->fragment_id) != fc->fragment_id)
343 return GNUNET_SYSERR; /* not our ACK */ 356 return GNUNET_SYSERR; /* not our ACK */
344 abits = GNUNET_ntohll (fa->bits); 357 abits = GNUNET_ntohll (fa->bits);
345 if ((GNUNET_YES == fc->wack) && (abits == (fc->acks & abits))) 358 if ( (GNUNET_YES == fc->wack) &&
359 (0 != fc->num_transmissions) )
346 { 360 {
347 /* normal ACK, can update running average of delay... */ 361 /* normal ACK, can update running average of delay... */
348 fc->wack = GNUNET_NO; 362 fc->wack = GNUNET_NO;
349 ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round); 363 ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round);
350 fc->delay.rel_value = 364 fc->delay.rel_value =
351 (ndelay.rel_value * fc->num_rounds + 3 * fc->delay.rel_value) / 4; 365 (ndelay.rel_value / fc->num_transmissions + 3 * fc->delay.rel_value) / 4;
366 fc->num_transmissions = 0;
352 } 367 }
353 GNUNET_STATISTICS_update (fc->stats, 368 GNUNET_STATISTICS_update (fc->stats,
354 _("# fragment acknowledgements received"), 1, 369 _("# fragment acknowledgements received"), 1,