sylveos

Toy Operating System
Log | Files | Refs

commit 7da8e0126f36fa58ce158549609bac9061c68aea
parent bdaf157b915565ce2802382e16bf2dfdfcfbcdf4
Author: Sylvia Ivory <git@sivory.net>
Date:   Sat, 31 Jan 2026 01:38:18 -0800

Directly write to Io.Writer for large buffers

Diffstat:
Mpi/devices/mini-uart.zig | 48+++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 45 insertions(+), 3 deletions(-)

diff --git a/pi/devices/mini-uart.zig b/pi/devices/mini-uart.zig @@ -139,6 +139,32 @@ pub fn enable_interrupts() Error!void { // var tx_list: std.ArrayList(u8) = .initBuffer(&tx_buffer); var rx_list: StackRingBuffer(u8, 4096) = .init(); +var rx_writer: ?*std.Io.Writer = null; +var rx_writer_written: usize = 0; + +pub fn switch_rx_writer(rx_w: ?*std.Io.Writer) !void { + const cs = mem.enter_critical_section(); + defer cs.exit(); + + rx_writer_written = 0; + + if (rx_w) |w| { + // Copy buffer into new writer + while (rx_list.pop()) |b| { + try w.writeByte(b); + rx_writer_written += 1; + } + } + + rx_writer = rx_w; +} + +pub fn get_rx_written() usize { + const cs = mem.enter_critical_section(); + defer cs.exit(); + + return rx_writer_written; +} noinline fn uart_handler(pc: usize) void { _ = pc; @@ -156,7 +182,13 @@ noinline fn uart_handler(pc: usize) void { if ((IIR & 0b100) != 0) { // can't do anything with error - rx_list.push(read_byte_raw()) catch {}; + const b = read_byte_raw(); + if (rx_writer) |w| { + rx_writer_written += 1; + w.writeByte(b) catch {}; + } else { + rx_list.push(b) catch {}; + } } // TODO; figure out why TX interrupts aren't working @@ -310,8 +342,18 @@ fn stream(io_r: *std.Io.Reader, io_w: *std.Io.Writer, limit: std.Io.Limit) !usiz _ = io_r; if (limit.toInt()) |max| { - for (0..max) |_| { - try io_w.writeByte(read_byte_blocking(null).?); + if (max > 128) { + // Use direct writes when there's a large buffer + try switch_rx_writer(io_w); + + while (get_rx_written() < max) {} + + try switch_rx_writer(null); + } else { + // Small buffers should just read blocking + for (0..max) |_| { + try io_w.writeByte(read_byte_blocking(null).?); + } } return max;