serial: make ringbuf write operations atomic
This commit is contained in:
parent
a25ab04b0d
commit
43add13fea
2 changed files with 16 additions and 6 deletions
|
@ -31,7 +31,7 @@ size_t ringbuf_read(void *dest, struct ringbuf *buf, size_t len)
|
||||||
{
|
{
|
||||||
uint8_t *tmp = dest;
|
uint8_t *tmp = dest;
|
||||||
|
|
||||||
while (len-- > 0 && buf->len > 0) {
|
while (len-- && buf->len) {
|
||||||
*tmp++ = buf->data[buf->rpos++];
|
*tmp++ = buf->data[buf->rpos++];
|
||||||
buf->len--;
|
buf->len--;
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ size_t ringbuf_write(struct ringbuf *buf, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
const uint8_t *tmp = src;
|
const uint8_t *tmp = src;
|
||||||
|
|
||||||
while (len-- > 0 && buf->len < buf->capacity) {
|
while (len-- && buf->len != buf->capacity) {
|
||||||
buf->data[buf->wpos++] = *tmp++;
|
buf->data[buf->wpos++] = *tmp++;
|
||||||
buf->len++;
|
buf->len++;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <ardix/serial.h>
|
#include <ardix/serial.h>
|
||||||
|
|
||||||
#include <arch/serial.h>
|
#include <arch/serial.h>
|
||||||
|
#include <arch/sched.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
@ -46,14 +47,23 @@ void serial_exit(struct serial_interface *interface)
|
||||||
|
|
||||||
ssize_t serial_read(void *dest, struct serial_interface *interface, size_t len)
|
ssize_t serial_read(void *dest, struct serial_interface *interface, size_t len)
|
||||||
{
|
{
|
||||||
return (ssize_t)ringbuf_read(dest, interface->rx, len);
|
ssize_t ret;
|
||||||
|
|
||||||
|
sched_atomic_enter();
|
||||||
|
ret = (ssize_t)ringbuf_read(dest, interface->rx, len);
|
||||||
|
sched_atomic_leave();
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t serial_write(struct serial_interface *interface, const void *data, size_t len)
|
ssize_t serial_write(struct serial_interface *interface, const void *data, size_t len)
|
||||||
{
|
{
|
||||||
ssize_t ret = (ssize_t)ringbuf_write(interface->tx, data, len);
|
ssize_t ret;
|
||||||
if (ret > 0)
|
|
||||||
arch_serial_notify(interface);
|
sched_atomic_enter();
|
||||||
|
ret = (ssize_t)ringbuf_write(interface->tx, data, len);
|
||||||
|
sched_atomic_leave();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue