cleanup: namespace Montauk (capital M) => montauk::abi

This commit is contained in:
2026-06-16 09:09:16 +02:00
parent b091af7653
commit e3dc1e881d
165 changed files with 758 additions and 758 deletions
+1 -1
View File
@@ -424,7 +424,7 @@ namespace Hal {
reinitProgress(0x02); // TSS
Hal::LoadTSS();
reinitProgress(0x03); // Syscalls
Montauk::InitializeSyscalls();
montauk::abi::InitializeSyscalls();
// Re-set GS base for BSP (lost during S3)
{
auto* bsp = Smp::GetCpuData(0);
+1 -1
View File
@@ -17,7 +17,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
// Audio handle convention:
// 0x00 - 0x07 : Mixer virtual streams (one per opened audio handle)
+1 -1
View File
@@ -12,7 +12,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static int64_t Sys_BtScan(BtScanResult* buf, int maxCount, uint32_t timeoutMs) {
if (!buf || maxCount <= 0) return -1;
+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once
#define MONTAUK_BUILD_NUMBER 24
#define MONTAUK_BUILD_NUMBER 25
+1 -1
View File
@@ -12,7 +12,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static constexpr int ClipboardMaxSlots = 32;
+1 -1
View File
@@ -3,7 +3,7 @@
#include <Sched/Scheduler.hpp>
#include <Ipc/Ipc.hpp>
namespace Montauk {
namespace montauk::abi {
static Sched::Process* GetRedirTarget(Sched::Process* proc) {
if (!proc || !proc->redirected) return nullptr;
+1 -1
View File
@@ -9,7 +9,7 @@
#include "Syscall.hpp"
#include "../Sched/CrashReport.hpp"
namespace Montauk {
namespace montauk::abi {
static int64_t Sys_CrashReport(CrashReportInfo* out) {
if (!out) return 0;
+1 -1
View File
@@ -22,7 +22,7 @@
#include <Drivers/Storage/BlockDevice.hpp>
#include <Drivers/Storage/Nvme.hpp>
namespace Montauk {
namespace montauk::abi {
static void dl_strcpy(char* dst, const char* src, int max) {
int i = 0;
+1 -1
View File
@@ -17,7 +17,7 @@
#include <Ipc/Ipc.hpp>
#include "Path.hpp"
namespace Montauk {
namespace montauk::abi {
static int Sys_Open(const char* path) {
char resolved[256];
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
+1 -1
View File
@@ -16,7 +16,7 @@
#include "Common.hpp"
#include "../Libraries/flanterm/src/flanterm.h"
namespace Montauk {
namespace montauk::abi {
static void Sys_FbInfo(FbInfo* out) {
if (out == nullptr) return;
+1 -1
View File
@@ -10,7 +10,7 @@
#include <Memory/HHDM.hpp>
#include <Memory/PageFrameAllocator.hpp>
namespace Montauk {
namespace montauk::abi {
// Per-process heap allocation tracking (separate from Process struct to avoid bloating it)
struct HeapAlloc {
+1 -1
View File
@@ -10,7 +10,7 @@
#include "BuildNo.hpp"
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static void Sys_GetInfo(SysInfo* outInfo) {
if (outInfo == nullptr) return;
+1 -1
View File
@@ -7,7 +7,7 @@
#pragma once
#include <Drivers/Input/InputEvents.hpp>
namespace Montauk {
namespace montauk::abi {
static uint64_t Sys_InputWait(uint64_t observedSerial, uint64_t timeoutMs) {
return Drivers::InputEvents::WaitForChange(observedSerial, timeoutMs);
+1 -1
View File
@@ -11,7 +11,7 @@
#include "Common.hpp"
#include "Path.hpp"
namespace Montauk {
namespace montauk::abi {
static constexpr uint32_t RedirOutputStreamCapacity = 64 * 1024;
+1 -1
View File
@@ -9,7 +9,7 @@
#include <Sched/Scheduler.hpp>
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static int Sys_DupHandle(int handle) {
return Ipc::DupHandle(handle);
+1 -1
View File
@@ -11,7 +11,7 @@
#include "Common.hpp"
namespace Montauk {
namespace montauk::abi {
static bool Sys_IsKeyAvailable() {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc && proc->redirected) {
+1 -1
View File
@@ -14,7 +14,7 @@
#include <Libraries/Memory.hpp>
#include <Libraries/String.hpp>
namespace Montauk {
namespace montauk::abi {
// Maximum libraries per process
static constexpr int MaxLibsPerProcess = 8;
+1 -1
View File
@@ -9,7 +9,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static void Sys_MemStats(MemStats* out) {
if (out == nullptr) return;
+1 -1
View File
@@ -9,7 +9,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static void Sys_MouseState(MouseState* out) {
if (out == nullptr) return;
+1 -1
View File
@@ -19,7 +19,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static uint16_t g_pingSeq = 0;
static constexpr uint16_t PING_ID = 0x2E01; // "ZE"
+1 -1
View File
@@ -9,7 +9,7 @@
#include <Sched/Scheduler.hpp>
#include <Libraries/Memory.hpp>
namespace Montauk {
namespace montauk::abi {
static int ParseDrivePrefix(const char* path, int* outPrefixLen = nullptr) {
if (path == nullptr || path[0] < '0' || path[0] > '9') return -1;
+1 -1
View File
@@ -15,7 +15,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
// Pending graceful power-off request, set by the desktop and consumed by
// login.elf. Kernel-global IPC channel (one outstanding request system-wide).
+1 -1
View File
@@ -18,7 +18,7 @@
#include "WinServer.hpp"
#include "Path.hpp"
namespace Montauk {
namespace montauk::abi {
static void Sys_Exit(int exitCode) {
(void)exitCode;
Sched::ExitProcess();
+1 -1
View File
@@ -7,7 +7,7 @@
#pragma once
#include <cstdint>
namespace Montauk {
namespace montauk::abi {
// ---- Random number generation ----
// Uses RDTSC mixed with xorshift64* PRNG for entropy.
+1 -1
View File
@@ -15,7 +15,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static void dl_strcpy_s(char* dst, const char* src, int max) {
int i = 0;
+1 -1
View File
@@ -42,7 +42,7 @@
// Assembly entry point
extern "C" void SyscallEntry();
namespace Montauk {
namespace montauk::abi {
static constexpr uint64_t kMaxPrintableStringBytes = 4096;
static constexpr uint64_t kMaxPathBytes = 256;
+1 -1
View File
@@ -8,7 +8,7 @@
#include <cstdint>
#include <cstddef>
namespace Montauk {
namespace montauk::abi {
// Syscall numbers
+1 -1
View File
@@ -10,7 +10,7 @@
#include "Common.hpp"
namespace Montauk {
namespace montauk::abi {
static void Sys_Print(const char* text) {
auto* proc = Sched::GetCurrentProcessPtr();
+1 -1
View File
@@ -10,7 +10,7 @@
#include "Syscall.hpp"
namespace Montauk {
namespace montauk::abi {
static uint64_t Sys_GetTicks() {
return Timekeeping::GetTicks();
}
+1 -1
View File
@@ -6,7 +6,7 @@
#include <Sched/Scheduler.hpp>
#include <Memory/Paging.hpp>
namespace Montauk::UserMemory {
namespace montauk::abi::UserMemory {
static constexpr uint64_t USER_SPACE_END = 0x0000800000000000ULL;
+7 -7
View File
@@ -94,7 +94,7 @@ namespace WinServer {
ResetSlotLocked(slot);
}
static int SendEventLocked(int windowId, const Montauk::WinEvent* event) {
static int SendEventLocked(int windowId, const montauk::abi::WinEvent* event) {
if (windowId < 0 || windowId >= MaxWindows || event == nullptr) return -1;
WindowSlot& slot = g_slots[windowId];
if (!slot.used || slot.eventMailbox == nullptr) return -1;
@@ -200,7 +200,7 @@ namespace WinServer {
return 0;
}
int Poll(int windowId, int callerPid, Montauk::WinEvent* outEvent) {
int Poll(int windowId, int callerPid, montauk::abi::WinEvent* outEvent) {
WsGuard guard;
if (windowId < 0 || windowId >= MaxWindows || outEvent == nullptr) return -1;
@@ -213,13 +213,13 @@ namespace WinServer {
return rc > 0 ? 1 : 0;
}
int Enumerate(Montauk::WinInfo* outArray, int maxCount) {
int Enumerate(montauk::abi::WinInfo* outArray, int maxCount) {
WsGuard guard;
int count = 0;
for (int i = 0; i < MaxWindows && count < maxCount; i++) {
if (!g_slots[i].used) continue;
Montauk::WinInfo& info = outArray[count];
montauk::abi::WinInfo& info = outArray[count];
info.id = i;
info.ownerPid = g_slots[i].ownerPid;
for (int j = 0; j < 64; j++) info.title[j] = g_slots[i].title[j];
@@ -263,7 +263,7 @@ namespace WinServer {
return result;
}
int SendEvent(int windowId, const Montauk::WinEvent* event) {
int SendEvent(int windowId, const montauk::abi::WinEvent* event) {
WsGuard guard;
return SendEventLocked(windowId, event);
}
@@ -346,7 +346,7 @@ namespace WinServer {
WindowSlot& slot = g_slots[windowId];
if (!slot.used || slot.ownerPid != callerPid) return -1;
slot.flags = flags & Montauk::WIN_FLAG_FULLSCREEN;
slot.flags = flags & montauk::abi::WIN_FLAG_FULLSCREEN;
return 0;
}
@@ -356,7 +356,7 @@ namespace WinServer {
if (scale > 2) scale = 2;
g_uiScale = scale;
Montauk::WinEvent ev{};
montauk::abi::WinEvent ev{};
ev.type = 4;
ev.scale.scale = scale;
for (int i = 0; i < MaxWindows; i++) {
+3 -3
View File
@@ -31,11 +31,11 @@ namespace WinServer {
uint64_t& heapNext, uint64_t& outVa);
int Destroy(int windowId, int callerPid);
int Present(int windowId, int callerPid);
int Poll(int windowId, int callerPid, Montauk::WinEvent* outEvent);
int Enumerate(Montauk::WinInfo* outArray, int maxCount);
int Poll(int windowId, int callerPid, montauk::abi::WinEvent* outEvent);
int Enumerate(montauk::abi::WinInfo* outArray, int maxCount);
uint64_t Map(int windowId, int callerPid, uint64_t callerPml4, uint64_t& heapNext);
int Unmap(int windowId, int callerPid, uint64_t callerPml4);
int SendEvent(int windowId, const Montauk::WinEvent* event);
int SendEvent(int windowId, const montauk::abi::WinEvent* event);
int Resize(int windowId, int callerPid, uint64_t ownerPml4, int newW, int newH,
uint64_t& heapNext, uint64_t& outVa);
void CleanupProcess(int pid);
+1 -1
View File
@@ -12,7 +12,7 @@
#include "Syscall.hpp"
#include "WinServer.hpp"
namespace Montauk {
namespace montauk::abi {
static int Sys_WinCreate(const char* title, int w, int h, WinCreateResult* result) {
if (result == nullptr || title == nullptr) return -1;
+11 -11
View File
@@ -437,15 +437,15 @@ namespace Drivers::Audio::Mixer {
int Control(int handle, int cmd, int value) {
// Master-scope commands ignore the handle.
switch (cmd) {
case Montauk::AUDIO_CTL_SET_MASTER_VOLUME:
case montauk::abi::AUDIO_CTL_SET_MASTER_VOLUME:
SetMasterVolume(value);
return 0;
case Montauk::AUDIO_CTL_GET_MASTER_VOLUME:
case montauk::abi::AUDIO_CTL_GET_MASTER_VOLUME:
return GetMasterVolume();
case Montauk::AUDIO_CTL_SET_MASTER_MUTE:
case montauk::abi::AUDIO_CTL_SET_MASTER_MUTE:
SetMasterMute(value != 0);
return 0;
case Montauk::AUDIO_CTL_GET_MASTER_MUTE:
case montauk::abi::AUDIO_CTL_GET_MASTER_MUTE:
return GetMasterMute() ? 1 : 0;
}
@@ -458,27 +458,27 @@ namespace Drivers::Audio::Mixer {
int rv = -1;
bool changed = false;
switch (cmd) {
case Montauk::AUDIO_CTL_SET_VOLUME: {
case montauk::abi::AUDIO_CTL_SET_VOLUME: {
int v = value; if (v < 0) v = 0; if (v > 100) v = 100;
if (s.volume != (uint8_t)v) { s.volume = (uint8_t)v; changed = true; }
rv = 0;
break;
}
case Montauk::AUDIO_CTL_GET_VOLUME:
case montauk::abi::AUDIO_CTL_GET_VOLUME:
rv = s.volume;
break;
case Montauk::AUDIO_CTL_GET_POS:
case montauk::abi::AUDIO_CTL_GET_POS:
rv = (int)(s.consumedInputBytes & 0x7FFFFFFF);
break;
case Montauk::AUDIO_CTL_PAUSE:
case montauk::abi::AUDIO_CTL_PAUSE:
if (s.paused != (value != 0)) { s.paused = (value != 0); changed = true; }
rv = 0;
break;
case Montauk::AUDIO_CTL_SET_MUTE:
case montauk::abi::AUDIO_CTL_SET_MUTE:
if (s.muted != (value != 0)) { s.muted = (value != 0); changed = true; }
rv = 0;
break;
case Montauk::AUDIO_CTL_GET_MUTE:
case montauk::abi::AUDIO_CTL_GET_MUTE:
rv = s.muted ? 1 : 0;
break;
default:
@@ -491,7 +491,7 @@ namespace Drivers::Audio::Mixer {
return rv;
}
int List(Montauk::AudioStreamInfo* buf, int maxCount) {
int List(montauk::abi::AudioStreamInfo* buf, int maxCount) {
if (!buf || maxCount <= 0) return 0;
g_lock.Acquire();
int count = 0;
+1 -1
View File
@@ -29,7 +29,7 @@ namespace Drivers::Audio::Mixer {
int Control(int handle, int cmd, int value);
// Enumerate all currently-active streams.
int List(Montauk::AudioStreamInfo* buf, int maxCount);
int List(montauk::abi::AudioStreamInfo* buf, int maxCount);
// Close every stream owned by `pid`. Called from the scheduler on process
// exit / kill so leaked handles do not occupy mixer slots.
+18 -18
View File
@@ -808,7 +808,7 @@ namespace Ipc {
int StreamReadHandle(int handle, uint8_t* out, int maxLen) {
if (out == nullptr) return -1;
if (maxLen > 0 && !Montauk::UserMemory::Range((uint64_t)out, (uint64_t)maxLen, true)) return -1;
if (maxLen > 0 && !montauk::abi::UserMemory::Range((uint64_t)out, (uint64_t)maxLen, true)) return -1;
HandleType type = HandleType::None;
Object* object = nullptr;
@@ -820,7 +820,7 @@ namespace Ipc {
int StreamWriteHandle(int handle, const uint8_t* data, int len) {
if (data == nullptr) return -1;
if (len > 0 && !Montauk::UserMemory::Range((uint64_t)data, (uint64_t)len, false)) return -1;
if (len > 0 && !montauk::abi::UserMemory::Range((uint64_t)data, (uint64_t)len, false)) return -1;
HandleType type = HandleType::None;
Object* object = nullptr;
@@ -963,9 +963,9 @@ namespace Ipc {
int MailboxSendCoalescedMouse(Mailbox* mailbox, uint32_t msgType, const void* data, uint16_t len) {
if (mailbox == nullptr || data == nullptr) return -1;
if (len != sizeof(Montauk::WinEvent)) return MailboxSend(mailbox, msgType, data, len);
if (len != sizeof(montauk::abi::WinEvent)) return MailboxSend(mailbox, msgType, data, len);
const Montauk::WinEvent* incoming = (const Montauk::WinEvent*)data;
const montauk::abi::WinEvent* incoming = (const montauk::abi::WinEvent*)data;
if (incoming->type != 1 || incoming->mouse.scroll != 0)
return MailboxSend(mailbox, msgType, data, len);
@@ -983,7 +983,7 @@ namespace Ipc {
uint32_t idx = (mailbox->head + MaxMailboxMessages - 1) % MaxMailboxMessages;
MailboxMessage& latest = mailbox->messages[idx];
if (latest.type == msgType && latest.size == len && !latest.hasAttachment) {
const Montauk::WinEvent* queued = (const Montauk::WinEvent*)latest.data;
const montauk::abi::WinEvent* queued = (const montauk::abi::WinEvent*)latest.data;
bool queuedTransition = queued->type != 1 ||
queued->mouse.scroll != 0 ||
queued->mouse.buttons != queued->mouse.prev_buttons;
@@ -1060,7 +1060,7 @@ namespace Ipc {
}
int MailboxSendHandle(int handle, uint32_t msgType, const void* data, uint16_t len, int attachHandle) {
if (len > 0 && (data == nullptr || !Montauk::UserMemory::Range((uint64_t)data, len, false))) return -1;
if (len > 0 && (data == nullptr || !montauk::abi::UserMemory::Range((uint64_t)data, len, false))) return -1;
HandleType type = HandleType::None;
Object* object = nullptr;
@@ -1072,12 +1072,12 @@ namespace Ipc {
}
int MailboxRecvHandle(int handle, uint32_t* msgType, void* data, uint16_t* inOutLen, int* outAttachHandle) {
if (inOutLen == nullptr || !Montauk::UserMemory::Writable<uint16_t>((uint64_t)inOutLen)) return -1;
if (inOutLen == nullptr || !montauk::abi::UserMemory::Writable<uint16_t>((uint64_t)inOutLen)) return -1;
uint16_t requestedLen = *inOutLen;
if (msgType != nullptr && !Montauk::UserMemory::Writable<uint32_t>((uint64_t)msgType)) return -1;
if (requestedLen > 0 && (data == nullptr || !Montauk::UserMemory::Range((uint64_t)data, requestedLen, true))) return -1;
if (outAttachHandle != nullptr && !Montauk::UserMemory::Writable<int>((uint64_t)outAttachHandle)) return -1;
if (msgType != nullptr && !montauk::abi::UserMemory::Writable<uint32_t>((uint64_t)msgType)) return -1;
if (requestedLen > 0 && (data == nullptr || !montauk::abi::UserMemory::Range((uint64_t)data, requestedLen, true))) return -1;
if (outAttachHandle != nullptr && !montauk::abi::UserMemory::Writable<int>((uint64_t)outAttachHandle)) return -1;
HandleType type = HandleType::None;
Object* object = nullptr;
@@ -1139,7 +1139,7 @@ namespace Ipc {
int FileReadHandle(int handle, uint8_t* buffer, uint64_t offset, uint64_t size) {
if (buffer == nullptr) return -1;
if (size > 0 && !Montauk::UserMemory::Range((uint64_t)buffer, size, true)) return -1;
if (size > 0 && !montauk::abi::UserMemory::Range((uint64_t)buffer, size, true)) return -1;
HandleType type = HandleType::None;
Object* object = nullptr;
@@ -1151,7 +1151,7 @@ namespace Ipc {
int FileWriteHandle(int handle, const uint8_t* buffer, uint64_t offset, uint64_t size) {
if (buffer == nullptr) return -1;
if (size > 0 && !Montauk::UserMemory::Range((uint64_t)buffer, size, false)) return -1;
if (size > 0 && !montauk::abi::UserMemory::Range((uint64_t)buffer, size, false)) return -1;
HandleType type = HandleType::None;
Object* object = nullptr;
@@ -1371,7 +1371,7 @@ namespace Ipc {
int SocketSendHandle(int handle, const uint8_t* data, uint32_t len) {
if (data == nullptr) return -1;
if (len > 0 && !Montauk::UserMemory::Range((uint64_t)data, len, false)) return -1;
if (len > 0 && !montauk::abi::UserMemory::Range((uint64_t)data, len, false)) return -1;
Socket* socket = nullptr;
uint32_t rights = 0;
@@ -1387,7 +1387,7 @@ namespace Ipc {
int SocketRecvHandle(int handle, uint8_t* buffer, uint32_t maxLen) {
if (buffer == nullptr) return -1;
if (maxLen > 0 && !Montauk::UserMemory::Range((uint64_t)buffer, maxLen, true)) return -1;
if (maxLen > 0 && !montauk::abi::UserMemory::Range((uint64_t)buffer, maxLen, true)) return -1;
Socket* socket = nullptr;
uint32_t rights = 0;
@@ -1406,7 +1406,7 @@ namespace Ipc {
int SocketSendToHandle(int handle, const uint8_t* data, uint32_t len, uint32_t destIp, uint16_t destPort) {
if (data == nullptr) return -1;
if (len > 0 && !Montauk::UserMemory::Range((uint64_t)data, len, false)) return -1;
if (len > 0 && !montauk::abi::UserMemory::Range((uint64_t)data, len, false)) return -1;
Socket* socket = nullptr;
uint32_t rights = 0;
@@ -1437,9 +1437,9 @@ namespace Ipc {
int SocketRecvFromHandle(int handle, uint8_t* buffer, uint32_t maxLen, uint32_t* srcIp, uint16_t* srcPort) {
if (buffer == nullptr) return -1;
if (maxLen > 0 && !Montauk::UserMemory::Range((uint64_t)buffer, maxLen, true)) return -1;
if (srcIp != nullptr && !Montauk::UserMemory::Writable<uint32_t>((uint64_t)srcIp)) return -1;
if (srcPort != nullptr && !Montauk::UserMemory::Writable<uint16_t>((uint64_t)srcPort)) return -1;
if (maxLen > 0 && !montauk::abi::UserMemory::Range((uint64_t)buffer, maxLen, true)) return -1;
if (srcIp != nullptr && !montauk::abi::UserMemory::Writable<uint32_t>((uint64_t)srcIp)) return -1;
if (srcPort != nullptr && !montauk::abi::UserMemory::Writable<uint16_t>((uint64_t)srcPort)) return -1;
Socket* socket = nullptr;
uint32_t rights = 0;
+1 -1
View File
@@ -185,7 +185,7 @@ extern "C" void kmain() {
Drivers::USB::Bluetooth::ServiceDeferredInit();
Hal::LoadTSS();
Montauk::InitializeSyscalls();
montauk::abi::InitializeSyscalls();
Sched::Initialize();
Ipc::Initialize();
+1 -1
View File
@@ -200,7 +200,7 @@ namespace Memory {
FreeRange(ptr, (size_t)n * 0x1000);
}
void PageFrameAllocator::GetStats(Montauk::MemStats* out) {
void PageFrameAllocator::GetStats(montauk::abi::MemStats* out) {
if (!out) return;
Lock.Acquire();
uint64_t freeBytes = 0;
+1 -1
View File
@@ -31,7 +31,7 @@ public:
void Free(void* ptr);
void Free(void* ptr, int n);
void GetStats(Montauk::MemStats* out);
void GetStats(montauk::abi::MemStats* out);
};
extern PageFrameAllocator* g_pfa;
+2 -2
View File
@@ -1089,8 +1089,8 @@ namespace Sched {
// Release process-scoped IPC handles/mappings before tearing down the address space.
Ipc::CleanupProcessSlot(slot, exitingPid, proc.pml4Phys);
Montauk::CleanupHeapForSlot(slot, proc.pml4Phys);
Montauk::CleanupLibTable(slot);
montauk::abi::CleanupHeapForSlot(slot, proc.pml4Phys);
montauk::abi::CleanupLibTable(slot);
proc.waitingForPid = -1;
proc.sleepUntilTick = 0;
+1 -1
View File
@@ -82,7 +82,7 @@ namespace Sched {
uint8_t* inBuf = nullptr; // 4KB ring: parent writes, child reads (getchar)
volatile uint32_t inHead = 0;
volatile uint32_t inTail = 0;
Montauk::KeyEvent keyBuf[64]; // parent injects, child reads (getkey/iskeyavailable)
montauk::abi::KeyEvent keyBuf[64]; // parent injects, child reads (getkey/iskeyavailable)
volatile uint32_t keyHead = 0;
volatile uint32_t keyTail = 0;
static constexpr uint32_t IoBufSize = 4096;