From be50f8b9f9e96f6bd20e816f6e44c1607278c3e9 Mon Sep 17 00:00:00 2001
From: Kaspar Schleiser <kaspar@schleiser.de>
Date: Mon, 4 May 2015 11:08:16 +0200
Subject: [PATCH] sys: newlib: use double-lock scheme for uart ringbuffer

---
 sys/newlib/syscalls.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/sys/newlib/syscalls.c b/sys/newlib/syscalls.c
index a0d7837614..a6aa78272e 100644
--- a/sys/newlib/syscalls.c
+++ b/sys/newlib/syscalls.c
@@ -54,7 +54,7 @@ caddr_t heap_top = (caddr_t)&_sheap + 4;
 /**
  * @brief use mutex for waiting on incoming UART chars
  */
-static mutex_t uart_rx_mutex;
+static mutex_t uart_rx_mutex = MUTEX_INIT;
 static char rx_buf_mem[STDIO_RX_BUFSIZE];
 static ringbuffer_t rx_buf;
 #endif
@@ -65,16 +65,14 @@ static ringbuffer_t rx_buf;
 void rx_cb(void *arg, char data)
 {
     (void)arg;
-
-#ifdef MODULE_UART0
+#ifndef MODULE_UART0
+    ringbuffer_add_one(&rx_buf, data);
+    mutex_unlock(&uart_rx_mutex);
+#else
     if (uart0_handler_pid) {
         uart0_handle_incoming(data);
-
         uart0_notify_thread();
     }
-#else
-    ringbuffer_add_one(&rx_buf, data);
-    mutex_unlock(&uart_rx_mutex);
 #endif
 }
 
@@ -84,7 +82,7 @@ void rx_cb(void *arg, char data)
 void _init(void)
 {
 #ifndef MODULE_UART0
-    mutex_init(&uart_rx_mutex);
+    mutex_lock(&uart_rx_mutex);
     ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_RX_BUFSIZE);
 #endif
     uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);
@@ -205,10 +203,11 @@ int _open_r(struct _reent *r, const char *name, int mode)
 int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
 {
 #ifndef MODULE_UART0
-    while (rx_buf.avail == 0) {
-        mutex_lock(&uart_rx_mutex);
-    }
-    return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail);
+    mutex_lock(&uart_rx_mutex);
+
+    count = count < rx_buf.avail ? count : rx_buf.avail;
+
+    return ringbuffer_get(&rx_buf, (char*)buffer, count);
 #else
     char *res = (char*)buffer;
     res[0] = (char)uart0_readc();
-- 
GitLab