serialqueue: Improve timing of multiple retransmits
If a retransmit is triggered by a nak, then it is not necessary to increase the rto. The next retransmit time should be based on the expected reception of the first retransmitted message, not the last. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
7faa5fe233
commit
61325c0a14
|
@ -102,14 +102,12 @@ pollreactor_add_timer(struct pollreactor *pr, int pos, void *callback)
|
||||||
pr->timers[pos].waketime = PR_NEVER;
|
pr->timers[pos].waketime = PR_NEVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Return the last schedule wake-up time for a timer
|
// Return the last schedule wake-up time for a timer
|
||||||
static double
|
static double
|
||||||
pollreactor_get_timer(struct pollreactor *pr, int pos)
|
pollreactor_get_timer(struct pollreactor *pr, int pos)
|
||||||
{
|
{
|
||||||
return pr->timers[pos].waketime;
|
return pr->timers[pos].waketime;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set the wake-up time for a given timer
|
// Set the wake-up time for a given timer
|
||||||
static void
|
static void
|
||||||
|
@ -568,12 +566,14 @@ retransmit_event(struct serialqueue *sq, double eventtime)
|
||||||
|
|
||||||
// Retransmit all pending messages
|
// Retransmit all pending messages
|
||||||
uint8_t buf[MESSAGE_MAX * MESSAGE_SEQ_MASK + 1];
|
uint8_t buf[MESSAGE_MAX * MESSAGE_SEQ_MASK + 1];
|
||||||
int buflen = 0;
|
int buflen = 0, first_buflen = 0;
|
||||||
buf[buflen++] = MESSAGE_SYNC;
|
buf[buflen++] = MESSAGE_SYNC;
|
||||||
struct queue_message *qm;
|
struct queue_message *qm;
|
||||||
list_for_each_entry(qm, &sq->sent_queue, node) {
|
list_for_each_entry(qm, &sq->sent_queue, node) {
|
||||||
memcpy(&buf[buflen], qm->msg, qm->len);
|
memcpy(&buf[buflen], qm->msg, qm->len);
|
||||||
buflen += qm->len;
|
buflen += qm->len;
|
||||||
|
if (!first_buflen)
|
||||||
|
first_buflen = qm->len;
|
||||||
}
|
}
|
||||||
ret = write(sq->serial_fd, buf, buflen);
|
ret = write(sq->serial_fd, buf, buflen);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -581,13 +581,17 @@ retransmit_event(struct serialqueue *sq, double eventtime)
|
||||||
sq->bytes_retransmit += buflen;
|
sq->bytes_retransmit += buflen;
|
||||||
|
|
||||||
// Update rto
|
// Update rto
|
||||||
|
if (pollreactor_get_timer(&sq->pr, SQPT_RETRANSMIT) != PR_NOW) {
|
||||||
sq->rto *= 2.0;
|
sq->rto *= 2.0;
|
||||||
if (sq->rto > MAX_RTO)
|
if (sq->rto > MAX_RTO)
|
||||||
sq->rto = MAX_RTO;
|
sq->rto = MAX_RTO;
|
||||||
|
}
|
||||||
sq->retransmit_seq = sq->send_seq;
|
sq->retransmit_seq = sq->send_seq;
|
||||||
sq->rtt_sample_seq = 0;
|
sq->rtt_sample_seq = 0;
|
||||||
sq->idle_time = eventtime + buflen * sq->baud_adjust;
|
if (eventtime > sq->idle_time)
|
||||||
double waketime = sq->idle_time + sq->rto;
|
sq->idle_time = eventtime;
|
||||||
|
double waketime = sq->idle_time + first_buflen * sq->baud_adjust + sq->rto;
|
||||||
|
sq->idle_time += buflen * sq->baud_adjust;
|
||||||
|
|
||||||
pthread_mutex_unlock(&sq->lock);
|
pthread_mutex_unlock(&sq->lock);
|
||||||
return waketime;
|
return waketime;
|
||||||
|
|
Loading…
Reference in New Issue