/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. Licensed under the StarForth License, Version 1.0 */ /** * starkernel/doe_log.h — DoE (Design of Experiments) CSV logger * * Emits per-heartbeat-tick CSV rows to the serial log, tagged with * [HADES][DOE ] so they can be grepped cleanly from the QEMU log. * * Each row contains the 12 standard heartbeat snapshot fields plus * 3 APIC timer fields from TimeTrustState: * apic_ticks, time_trust_q48, variance_q48 * * A header row is printed automatically before the first data row. * * Always compiled in -- gating moved from a build-time flag * (HEARTBEAT_DOE_LOG) to a runtime one (g_doe_log_enabled below) so the * same build can run with or without per-tick instrumentation, toggled * live via the HB-ON/HB-OFF FORTH words (register_doe_log_words()), * no rebuild required. */ #ifndef STARKERNEL_DOE_LOG_H #define STARKERNEL_DOE_LOG_H #include "vm.h" /** * Runtime enable flag for doe_log_tick_row() below. Defaults to 1 * (matches the old HEARTBEAT_DOE_LOG=1 default -- instrumentation on * unless explicitly turned off). Toggled by HB-ON/HB-OFF; read, not * meant to be written directly outside those two words. */ extern int g_doe_log_enabled; /** * Emit one CSV row for the current heartbeat tick, unless * g_doe_log_enabled is 0 (a no-op then). Pulls APIC TimeTrustState via * heartbeat_state(). Prints the column header once, before the first row * ever emitted -- not re-printed on every HB-ON, so a session toggled * off and back on stays one continuous CSV rather than getting a second * header embedded partway through. * * @param vm VM instance (used for snapshot data) * @param snap Populated HeartbeatTickSnapshot from heartbeat_capture_tick_snapshot() */ void doe_log_tick_row(VM *vm, const HeartbeatTickSnapshot *snap); /** * Registers HB-ON ( -- ) and HB-OFF ( -- ), which set g_doe_log_enabled * to 1 and 0 respectively. */ void register_doe_log_words(VM *vm); #endif /* STARKERNEL_DOE_LOG_H */