nx_buf.nx
buildroot/runtime/nx_buf.nx
about
nx_buf.nx -- bounded append-only byte buffer with overflow detection.
Why this exists:
Every diagnostic emitter (nx_log, nx_panic, nx_hex, nx_metrics)
currently calls sys_write directly multiple times per record.
Three problems with that:
1. Records can be interleaved by other writers between the
first and last sys_write of a single logical record.
On a single-threaded process today this is rare; on a
multi-threaded NishiOS userspace tomorrow, every writer
racing to fd=2 will produce shredded log lines.
2. Every sys_write is a syscall. For a hot path (parser
guard fires, every fuzz iteration crashing) we pay
thousands of context switches that we could batch.
3. There is no centralised "did this record fit?" check.
Truncated diagnostic output is worse than dropped --
truncated misleads.
nx_buf solves all three: build the record in a fixed-capacity
byte buffer, hit overflow visibly (length > cap sets `overflow=1`
and stops appending), then flush atomically with one sys_write.
Design references:
Rust std::io::BufWriter
Linux pr_cont() vs pr_info() -- per-record buffering
Go bytes.Buffer
C stdio fwrite-then-fflush pattern
Discipline:
* caller picks capacity; nx_buf never reallocates (predictable)
* overflow is sticky -- once tripped, stays tripped until clear()
* never returns a partial write -- flush is all-or-nothing
* append family is intentionally minimal (bytes / cstr / int /
hex8); higher-level formatters compose from these.
dependencies 1 imports · 0 importers
imports: syscalls.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 48 | struct NxBuf |
consts
| 46 | const NX_MAGIC_12345: i64 = 12345 |
| 55 | const NX_BUF_BYTES: i64 = 32 // 4 fields x 8 |
functions
| 59 | func nx_buf_new(cap: i64) -> *NxBuf called by 1: main |
| 71 | func nx_buf_clear(b: *NxBuf) -> i64 called by 1: main |
| 77 | func nx_buf_len(b: *NxBuf) -> i64 { return b.len } called by 1: main |
| 78 | func nx_buf_cap(b: *NxBuf) -> i64 { return b.cap } |
| 79 | func nx_buf_overflow(b: *NxBuf) -> i64 { return b.overflow } called by 1: main |
| 83 | func nx_buf_append_byte(b: *NxBuf, x: i64) -> i64 |
| 91 | func nx_buf_append_bytes(b: *NxBuf, src: *u8, n: i64) -> i64 |
| 106 | func nx_buf_append_cstr(b: *NxBuf, s: *u8) -> i64 called by 1: main |
| 122 | func nx_buf_append_i64(b: *NxBuf, v: i64) -> i64 |
| 151 | func nx_buf_append_u8_hex(b: *NxBuf, v: i64) -> i64 |
| 171 | func nx_buf_flush(b: *NxBuf, fd: i64) -> i64 called by 1: main |
| 180 | func main() -> i64 |