aboutsummaryrefslogtreecommitdiff
path: root/src/fragmentation/fragmentation.c
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/fragmentation/fragmentation.c
parent7137a0aaac2e218ad3d0bf2ce6fcb69c9da088f7 (diff)
downloadgnunet-8fcb9162a53613e4df429136b2d8567f5ddd0a91.tar.gz
gnunet-8fcb9162a53613e4df429136b2d8567f5ddd0a91.zip
-improving fragmentation performance
Diffstat (limited to 'src/fragmentation/fragmentation.c')
-rw-r--r--src/fragmentation/fragmentation.c29
1 files changed, 22 insertions, 7 deletions
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,