Buffer the slip packet before sending.
On Mac OS X, sending the slip packet byte by byte results in an abysmal performance. The first byte takes up to 160ms to send, and each next byte approximately 250ms. The packet to request a data block is typically 7 bytes large, and therefore takes about 1660ms to send. Because a dive is transmitted as multiple smaller packets (typically 144 bytes without protocol overhead), downloading a single dive can easily take several seconds. However, when sending the entire slip packet at once, the time remains roughly identical to sending just the first byte. The result is that the time for sending a packet reduces significantly, proportional to the length of the packet. Under the hood, the slip packet is now internally buffered, and the buffer is send only when the entire packet is complete, or whenever the buffer gets full. But in practice, the buffer is large enough to always store an entire packet. In the original bug report, downloading 57 dives took about 40 minutes. After applying the patch, that time reduced to only 5 minutes!
This commit is contained in:
parent
6f7495dd3e
commit
8e0355c354
@ -148,6 +148,8 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned
|
||||
const unsigned char end[] = {END};
|
||||
const unsigned char esc_end[] = {ESC, ESC_END};
|
||||
const unsigned char esc_esc[] = {ESC, ESC_ESC};
|
||||
unsigned char buffer[32];
|
||||
unsigned int nbytes = 0;
|
||||
|
||||
#if 0
|
||||
// Send an initial END character to flush out any data that may have
|
||||
@ -179,15 +181,28 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned
|
||||
break;
|
||||
}
|
||||
|
||||
n = serial_write (device->port, seq, len);
|
||||
if (n != len) {
|
||||
return EXITCODE(n);
|
||||
// Flush the buffer if necessary.
|
||||
if (nbytes + len + sizeof(end) > sizeof(buffer)) {
|
||||
n = serial_write (device->port, buffer, nbytes);
|
||||
if (n != nbytes) {
|
||||
return EXITCODE(n);
|
||||
}
|
||||
|
||||
nbytes = 0;
|
||||
}
|
||||
|
||||
// Append the escaped character.
|
||||
memcpy(buffer + nbytes, seq, len);
|
||||
nbytes += len;
|
||||
}
|
||||
|
||||
// Send the END character to indicate the end of the packet.
|
||||
n = serial_write (device->port, end, sizeof (end));
|
||||
if (n != sizeof (end)) {
|
||||
// Append the END character to indicate the end of the packet.
|
||||
memcpy(buffer + nbytes, end, sizeof(end));
|
||||
nbytes += sizeof(end);
|
||||
|
||||
// Flush the buffer.
|
||||
n = serial_write (device->port, buffer, nbytes);
|
||||
if (n != nbytes) {
|
||||
return EXITCODE(n);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user