From ea27064d212bb340c1b9760a40ee89cfff0a20c9 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 24 Aug 2020 18:28:30 +0200 Subject: [PATCH 1/2] picolibc: make stdout buffering optional --- makefiles/pseudomodules.inc.mk | 1 + sys/picolibc_syscalls_default/syscalls.c | 28 +++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 510e6fecd8..b444af4ef7 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -86,6 +86,7 @@ PSEUDOMODULES += newlib_gnu_source PSEUDOMODULES += newlib_nano PSEUDOMODULES += openthread PSEUDOMODULES += picolibc +PSEUDOMODULES += picolibc_stdout_buffered PSEUDOMODULES += pktqueue PSEUDOMODULES += posix_headers PSEUDOMODULES += printf_float diff --git a/sys/picolibc_syscalls_default/syscalls.c b/sys/picolibc_syscalls_default/syscalls.c index 1782610d08..48b0b903e6 100644 --- a/sys/picolibc_syscalls_default/syscalls.c +++ b/sys/picolibc_syscalls_default/syscalls.c @@ -63,10 +63,12 @@ int kill(pid_t pid, int sig) #include "mutex.h" -static mutex_t picolibc_put_mutex = MUTEX_INIT; - +#ifndef PICOLIBC_STDOUT_BUFSIZE #define PICOLIBC_STDOUT_BUFSIZE 64 +#endif +#ifdef MODULE_PICOLIBC_STDOUT_BUFFERED +static mutex_t picolibc_put_mutex = MUTEX_INIT; static char picolibc_stdout[PICOLIBC_STDOUT_BUFSIZE]; static int picolibc_stdout_queued; @@ -81,10 +83,14 @@ static void _picolibc_flush(void) static int picolibc_put(char c, FILE *file) { (void)file; + mutex_lock(&picolibc_put_mutex); picolibc_stdout[picolibc_stdout_queued++] = c; - if (picolibc_stdout_queued == PICOLIBC_STDOUT_BUFSIZE || c == '\n') + + if (picolibc_stdout_queued == PICOLIBC_STDOUT_BUFSIZE || c == '\n') { _picolibc_flush(); + } + mutex_unlock(&picolibc_put_mutex); return 1; } @@ -98,6 +104,22 @@ static int picolibc_flush(FILE *file) return 0; } +#else +int picolibc_put(char c, FILE *file) +{ + (void)file; + stdio_write(&c, 1); + return 1; +} + +static int picolibc_flush(FILE *file) +{ + (void)file; + return 0; +} + +#endif + static int picolibc_get(FILE *file) { (void)file; From c94860d8fc6137e2d333c0c2eb098f41e2976e09 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 1 Sep 2020 12:04:26 +0200 Subject: [PATCH 2/2] makefiles/stdio: enable stdout buffering for CDC ACM, ethos, semihosting CDC ACM, ethos, Semihosting and SLIP all benefit from sending data out in larger chunks and will benefit from stdout buffering. `stdio_rtt` does have an internal TX buffer, so we don't need to do any buffering on top. With plain UART there was a slight advantage *without* buffering when testing with `tests/periph_uart_nonblocking` (with the non-blocking feature disabled). Since the removal of the buffering saves us some RAM and ROM, disable it by default there. This will be different with DMA enabled UARTs. --- makefiles/stdio.inc.mk | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/makefiles/stdio.inc.mk b/makefiles/stdio.inc.mk index 4c7749d2f9..5c1d3bff22 100644 --- a/makefiles/stdio.inc.mk +++ b/makefiles/stdio.inc.mk @@ -55,3 +55,10 @@ ifneq (,$(filter stdio_semihosting,$(USEMODULE))) USEMODULE += xtimer FEATURES_REQUIRED += cpu_core_cortexm endif + +# enable stdout buffering for modules that benefit from sending out buffers in larger chunks +ifneq (,$(filter picolibc,$(USEMODULE))) + ifneq (,$(filter stdio_cdc_acm stdio_ethos slipdev_stdio stdio_semihosting,$(USEMODULE))) + USEMODULE += picolibc_stdout_buffered + endif +endif