Skip to content

Commit

Permalink
Attempt to improve congestion control.
Browse files Browse the repository at this point in the history
This fixes two problems that were not immediately evident from porting
the NaCl code:

* Last-sent times should only be updated when a real block is sent, not
  for messages that are just acknowledgments.
* 1ms should not be arbitrarily added to every timeout to prevent
  spinning; it should only be added when there are no messages to be
  sent.
  • Loading branch information
impl committed Oct 14, 2013
1 parent c2337dc commit 3939c78
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
5 changes: 2 additions & 3 deletions libcurvecpr/lib/chicago.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,9 @@ void curvecpr_chicago_new (struct curvecpr_chicago *chicago)

chicago->rtt_phase = 0;

/* FIXME: This should be 1 second? */
chicago->wr_rate = 0;
chicago->wr_rate = 1000000000;

chicago->ns_last_update = 0;
chicago->ns_last_update = chicago->clock;
chicago->ns_last_edge = 0;
chicago->ns_last_doubling = 0;
chicago->ns_last_panic = 0;
Expand Down
24 changes: 17 additions & 7 deletions libcurvecpr/lib/messager.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ static int _send_block (struct curvecpr_messager *messager, struct curvecpr_bloc
sent because it could fail for any other arbitrary reason as well and need
to be reinvoked. */
}

/* Update the last sent time for timeout calcuations. */
messager->my_sent_clock = messager->chicago.clock;
}

/* Remove all the acknowledged ranges from the pending queue. */
Expand All @@ -418,9 +421,6 @@ static int _send_block (struct curvecpr_messager *messager, struct curvecpr_bloc
if (messager->their_eof && messager->their_contiguous_sent_bytes >= messager->their_total_bytes)
messager->their_final = 1;

/* Update the last sent time for timeout calcuations. */
messager->my_sent_clock = messager->chicago.clock;

/* Reset last received ID so we don't acknowledge an old message. */
messager->their_sent_id = 0;

Expand Down Expand Up @@ -490,13 +490,19 @@ long long curvecpr_messager_next_timeout (struct curvecpr_messager *messager)

long long at, timeout;

/* If we have anything to be written, we wouldn't spin at all, so don't include an
adjustment in the timeout for it in that case. */
int would_spin = 1;

curvecpr_chicago_refresh_clock(chicago);

at = chicago->clock + 60000000000LL; /* 60 seconds. */

if (!cf->ops.sendmarkq_is_full(messager)) {
/* If we have pending data, we might write it. */
if (!cf->ops.sendq_is_empty(messager)) {
would_spin = 0;

/* Write at the write rate. */
if (at > messager->my_sent_clock + chicago->wr_rate)
at = messager->my_sent_clock + chicago->wr_rate;
Expand All @@ -507,16 +513,20 @@ long long curvecpr_messager_next_timeout (struct curvecpr_messager *messager)
if (cf->ops.sendmarkq_head(messager, &block)) {
/* No earliest block. */
} else {
would_spin = 0;

if (at > block->clock + chicago->rtt_timeout)
at = block->clock + chicago->rtt_timeout;
}

/* If the current time is after the next action time, the timeout is 0. However, we
always have at least a 1 millisecond timeout to prevent the CPU from spinning. */
if (chicago->clock > at)
timeout = 1000000;
timeout = 0;
else
timeout = at - chicago->clock + 1000000;
timeout = at - chicago->clock;

/* Apply spinning adjustment if necessary. */
if (would_spin)
timeout += 1000000;

if (cf->ops.put_next_timeout)
cf->ops.put_next_timeout(messager, timeout);
Expand Down

0 comments on commit 3939c78

Please sign in to comment.