mirror of
https://github.com/halleysfifthinc/AVCLAN-Mockingboard.git
synced 2026-09-24 12:52:07 +00:00
Improve stdio_write_nonblock perf and indicator printing
This commit is contained in:
@@ -30,7 +30,7 @@ void stdio_init(void);
|
|||||||
// holds only '!'. In the overwrite case the buffer in front of that line is
|
// holds only '!'. In the overwrite case the buffer in front of that line is
|
||||||
// truncated, so a reader MUST tolerate one malformed buffer there. The return
|
// truncated, so a reader MUST tolerate one malformed buffer there. The return
|
||||||
// value is useful only for diagnostics.
|
// value is useful only for diagnostics.
|
||||||
bool stdio_write_nonblock(const void *buf, size_t len);
|
bool stdio_write_nonblock(const void *buf, uint8_t len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ static int stdio_putchar(char data, FILE *stream) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stdio_write_nonblock(const void *buf, size_t len) {
|
bool stdio_write_nonblock(const void *buf, uint8_t len) {
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -51,27 +51,32 @@ bool stdio_write_nonblock(const void *buf, size_t len) {
|
|||||||
// available space or because the ring is full. For the former case, the
|
// available space or because the ring is full. For the former case, the
|
||||||
// full indicator can be appended without truncating previously queued
|
// full indicator can be appended without truncating previously queued
|
||||||
// bytes.
|
// bytes.
|
||||||
|
// Goal is for the bang-indicator to be on its own line
|
||||||
|
uint8_t tmp = head;
|
||||||
if (space >= 3) {
|
if (space >= 3) {
|
||||||
tx0_buffer[(head + 1) & TX0_BUFFER_MASK] = '\n';
|
// Room for 3 normally implies the current head ends with a newline
|
||||||
tx0_buffer[(head + 2) & TX0_BUFFER_MASK] = '!';
|
// (avoids an unneeded double newline in most cases)
|
||||||
tx0_buffer[(head + 3) & TX0_BUFFER_MASK] = '\n';
|
tmp = (tmp + 1) & TX0_BUFFER_MASK;
|
||||||
tx0_Head = (uint8_t)((head + 3) & TX0_BUFFER_MASK);
|
tx0_buffer[tmp] = '!';
|
||||||
|
tmp = (tmp + 1) & TX0_BUFFER_MASK;
|
||||||
|
tx0_buffer[tmp] = '\n';
|
||||||
|
tx0_Head = tmp;
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { USART0.CTRLA |= USART_DREIE_bm; }
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { USART0.CTRLA |= USART_DREIE_bm; }
|
||||||
} else {
|
} else {
|
||||||
// No room for even the indicator, so it goes over the last three queued
|
// No room for even the indicator, so it goes over the last three queued
|
||||||
// bytes. `space` and the queued byte count always sum to
|
// bytes. The ISR already drains the ring, so DREIE needs no change.
|
||||||
// TX0_BUFFER_MASK, so space < 3 means at least 253 bytes are queued and
|
// Write in reverse order to more efficiently decrement
|
||||||
// all three writes land inside them. The ISR already drains the ring, so
|
tx0_buffer[tmp] = '\n';
|
||||||
// DREIE needs no change.
|
tmp = (tmp - 1) & TX0_BUFFER_MASK;
|
||||||
tx0_buffer[(head - 2) & TX0_BUFFER_MASK] = '\n';
|
tx0_buffer[tmp] = '!';
|
||||||
tx0_buffer[(head - 1) & TX0_BUFFER_MASK] = '!';
|
tmp = (tmp - 1) & TX0_BUFFER_MASK;
|
||||||
tx0_buffer[head] = '\n';
|
tx0_buffer[tmp] = '\n';
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t start = (uint8_t)((head + 1) & TX0_BUFFER_MASK);
|
const uint8_t start = (uint8_t)((head + 1) & TX0_BUFFER_MASK);
|
||||||
const size_t contiguous = TX0_BUFFER_SIZE - start;
|
const uint8_t contiguous = TX0_BUFFER_SIZE - start;
|
||||||
|
|
||||||
if (len <= contiguous) {
|
if (len <= contiguous) {
|
||||||
memcpy(&tx0_buffer[start], buf, len);
|
memcpy(&tx0_buffer[start], buf, len);
|
||||||
|
|||||||
Reference in New Issue
Block a user