Compare commits

...

2 commits

Author SHA1 Message Date
43f23cd7a2
disable interrupts while locked 2025-02-12 20:05:05 +01:00
bf16ead21f
start with line buffering 2025-02-12 18:42:03 +01:00
2 changed files with 32 additions and 3 deletions

View file

@ -1,13 +1,40 @@
#include "uart.h" #include "uart.h"
#include "output.h" #include "output.h"
#include "sync.h"
#define LINEBUF_SIZE 1024
struct {
struct spinlock lock;
unsigned int idx;
char buf[LINEBUF_SIZE];
} linebuf;
// TODO explicit initialization of linebuf
// TODO we could lock each function, that would be more efficient than locking/
// unlocking for every single char
// this also implicitly synchronizes accesses to uart
void putc_single(char c) {
spin_lock(&linebuf.lock);
linebuf.buf[linebuf.idx++] = c;
if (c == '\n' || linebuf.idx == LINEBUF_SIZE) {
for (unsigned int i = 0; i < linebuf.idx; i++) {
uart_write_char(linebuf.buf[i]);
}
linebuf.idx = 0;
}
spin_unlock(&linebuf.lock);
}
void putc(char c) { void putc(char c) {
uart_write_char(c); if (c == '\n') {
putc_single('\r');
}
putc_single(c);
} }
void puts(const char *s) { void puts(const char *s) {
for (const char *c = s; *c != '\0'; c++) { for (const char *c = s; *c != '\0'; c++) {
uart_write_char(*c); putc(*c);
} }
} }

View file

@ -1,11 +1,13 @@
#include "sync.h" #include "sync.h"
void spin_lock(struct spinlock *s) { void spin_lock(struct spinlock *s) {
__asm__ ("cli" :: );
while (atomic_exchange_explicit(&s->lock, 1, memory_order_acquire)) { while (atomic_exchange_explicit(&s->lock, 1, memory_order_acquire)) {
// spin __asm__ ("pause" :: );
} }
} }
void spin_unlock(struct spinlock *s) { void spin_unlock(struct spinlock *s) {
atomic_store_explicit(&s->lock, 0, memory_order_release); atomic_store_explicit(&s->lock, 0, memory_order_release);
__asm__ ("sti" :: );
} }