Reorganize source tree: kernel/, v3/, v4/ split and board infrastructure

Source tree reorganization:
- Move StarForth v3 engine to v3/ (src/, include/, Makefile)
- Move kernel to kernel/ (src/, include/, linker/, Makefile)
- Create v4/ skeleton for F18-ISA golden model (DECOMPOSITION.md, JUSTIFICATION.md)
- Move FABRIC-0..4.md to docs/fabric/
- Move ONTOLOGY.md and ROADMAP.md to docs/

Board infrastructure:
- Add boards/ser5/, boards/raspi/, boards/milkv/, boards/zynq7020/
- Each board has board.mk (ISA, CPU flags, boot recipe) and README.md
- Root Makefile becomes thin dispatcher: boot_image, all, clean, docs take TARGET
- make boot_image TARGET=SER5|RASPI|MILKV builds one GPT/MBR image per board
- ZYNQ7020 target exists but stops with clear error (ARMv7 port not built yet)
- scripts/mkdiskimage.sh builds disk images for all boards

Docs pipeline:
- docs/book/ with LaTeX master (main.tex) and Makefile
- pandoc converts Markdown to LaTeX at build time
- Two Lua filters: table-widths.lua (wide tables wrap), code-breaks.lua (inline code breaks)
- make docs builds single PDF (754 pages, 0 missing characters)
- make docs TARGET=<board> adds board appendix
- build/docs/<book|board>/meta.tex stamps git commit into PDF

Bug fixes:
- 42 include paths that only worked by accident now use correct relative paths
- clang-18 hardcode replaced with configurable CC variable (fixed aarch64 build)
- Pi 5: kernel_2712.img linked at 0x80000, .bss zeroed, memory reserved
- Doxyfile, .clang-tidy, README.md, Kconfig paths updated

Verified:
- Hosted v3 build passes 1012 tests, 0 failures
- SER5 image boots in QEMU (OVMF), POST passes, K exact (65536 = Q48_ONE)
- Milk-V image boots in QEMU (OpenSBI + U-Boot + bootefi), POST passes
- make clean TARGET=<board> removes only that board and its ISA objects
- make all builds all boards, hosted v3, and docs in one run

Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
rajames
2026-10-01 15:40:09 -04:00
co-authored by Junie
parent 3c709c115b
commit a8b70e88d3
630 changed files with 2646 additions and 2036 deletions
+54
View File
@@ -0,0 +1,54 @@
# include/
Public headers for the hosted StarForth VM (`src/`). Kernel-only headers
live under `include/starkernel/`.
**Core VM**
- `vm.h` — the `VM` struct and all core types (`DictEntry`, `DictPhysics`,
stacks, dictionary state); the central header most other files include.
- `vm_api.h` — external VM API surface.
- `vm_host.h`, `vm_debug.h`, `startup.h`, `version.h` — host integration,
debug utilities, startup sequencing, version string.
- `cli.h`, `repl.h`, `io.h`, `log.h` — CLI parsing, REPL loop, I/O, logging.
- `word_registry.h` — word registration system shared by every
`src/word_source/*.c` file.
- `compudynamics.h` — the generic compudynamics module: tuning-word/config
lookups (`cd_tuning_word()`, `cd_tuning_vm()`) consumed by `ssm_jacquard.c`.
**Memory / blocks**
- `memory_management.h`, `dictionary_management.h` — dictionary allocator
and search.
- `block_subsystem.h`, `blkcfg.h`, `blkio.h`, `blkio_factory.h` — logical→
physical block mapper and pluggable block I/O backends (file/RAM).
- `platform_alloc.h`, `platform_lock.h`, `platform_time.h` — platform
abstraction shims (hosted vs. kernel allocation/locking/timing).
**Physics-driven adaptive runtime (7 feedback loops)**
- `physics_runtime.h` — main physics coordinator.
- `physics_hotwords_cache.h` — Loop #1, execution-heat hot-words cache.
- `physics_metadata.h` — per-word `DictPhysics` metadata tracking.
- `physics_pipelining_metrics.h` — Loop #4, word-transition prediction.
- `physics_execution_hooks.h` — execution instrumentation hook points.
- `rolling_window_of_truth.h`, `rolling_window_knobs.h` — Loop #2 circular
execution-history buffer and its tuning knobs.
- `inference_engine.h` — Loops #5/#6, window-width and decay-slope
statistical inference.
- `dictionary_heat_optimization.h` — Loop #1 heat counters.
- `ssm_jacquard.h` — L8 Jacquard steady-state mode selector.
- `doe_metrics.h` — Design of Experiments (2^7 factorial) metrics.
- `profiler.h` — performance profiling hooks.
**Arithmetic / codegen**
- `q48_16.h` — Q48.16 deterministic fixed-point arithmetic (used instead of
IEEE-754 float specifically to keep cross-architecture behavior
bit-identical).
- `math_portable.h` — portable math helpers.
- `arch_detect.h`, `starforth_config.h` — architecture detection and the
build-flag fallback-default layer (used when a `.c` file is compiled by
hand without `make`).
- `vm_asm_opt.h`, `vm_asm_opt_arm64.h`, `vm_asm_opt_riscv64.h`,
`vm_inner_interp_asm.h`, `vm_inner_interp_arm64.h`,
`vm_inner_interp_riscv64.h` — per-architecture assembler-optimized inner
interpreter (`USE_ASM_OPT=1`).
See `include/starkernel/README.md` for the bare-metal kernel headers.
File diff suppressed because it is too large Load Diff
+144
View File
@@ -0,0 +1,144 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
*** StarForth ***
Block Subsystem Configuration API
----------------------------------
Purpose:
- Provide a common, reusable configuration interface for selecting
a "block subsystem" (FILE image vs RAM) and its geometry WITHOUT
touching any real I/O or backend code.
Notes:
- No file system calls; no mmap; no blkio includes.
- Geometries are computed deterministically from inputs only.
- FILE backend: we record the path and intent; size/blocks remain 0
until a real backend attaches later.
- RAM backend: ram_mb -> size_bytes -> blocks (floor to FBS multiple).
Typical flow:
- Parse CLI flags (--disk-img=<path> | --ram-disk=<MB>).
- Call blkcfg_init_from_options().
- Use g_blkcfg elsewhere to make decisions (later you'll attach drivers).
License: See LICENSE file. No warranty.
*/
#ifndef STARFORTH_BLKCFG_H
#define STARFORTH_BLKCFG_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BLKCFG_DEFAULT_FBS
#define BLKCFG_DEFAULT_FBS 1024u /* default Forth Block Size in bytes */
#endif
#ifndef BLKCFG_PATH_MAX
#define BLKCFG_PATH_MAX 4096
#endif
typedef enum {
BLKCFG_BACKEND_NONE = 0,
BLKCFG_BACKEND_FILE = 1,
BLKCFG_BACKEND_RAM = 2
} blkcfg_backend_t;
typedef struct {
blkcfg_backend_t backend; /* FILE or RAM (or NONE) */
uint32_t fbs; /* Forth Block Size (bytes) */
uint8_t read_only; /* 1 = intended RO, else 0 */
/* Geometry (no I/O performed to derive these) */
uint64_t size_bytes; /* For RAM: computed; FILE: 0 */
uint32_t blocks; /* For RAM: computed; FILE: 0 */
/* FILE plan (no I/O): path is recorded only */
char file_path[BLKCFG_PATH_MAX];
} blkcfg_t;
/* Global config (optional convenience) */
extern blkcfg_t g_blkcfg;
/**
* Initialize a block configuration from CLI-style options.
*
* Inputs:
* - disk_img_path: if non-NULL and non-empty => choose FILE backend
* - ram_mb: megabytes for RAM fallback (only used if no disk image)
* - fbs: forth block size (bytes). If 0 => BLKCFG_DEFAULT_FBS
* - read_only: intended read-only flag (advisory)
*
* Behavior:
* - FILE: record path, set blocks/size_bytes = 0 (unknown until attached)
* - RAM : compute size_bytes = ram_mb*MiB; blocks = size_bytes/fbs (floored)
*
* Returns:
* 0 on success; -1 on invalid args.
*/
int blkcfg_init_from_options(blkcfg_t *cfg,
const char *disk_img_path,
uint64_t ram_mb,
uint32_t fbs,
uint8_t read_only);
/**
* Format a single-line summary into 'dst' (capacity 'dst_cap' bytes).
* Example:
* "backend=FILE path=./disks/os.img fbs=1024 ro=0"
* "backend=RAM size=1024MB fbs=1024 blocks=1048576 ro=0"
*
* Returns number of bytes that would have been written (like snprintf).
*/
int blkcfg_format_summary(const blkcfg_t *cfg, char *dst, size_t dst_cap);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* STARFORTH_BLKCFG_H */
+178
View File
@@ -0,0 +1,178 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STARFORTH_BLKIO_H
#define STARFORTH_BLKIO_H
/* -----------------------------------------------------------------------------
StarForth - Block I/O Core API
- C99, deterministic core (no hidden malloc)
- Public types / errors / thin inline wrapper
- Backends provide a vtable implementing: open, close, read, write, flush, info
License: See LICENSE file. No warranty.
----------------------------------------------------------------------------- */
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BLKIO_FORTH_BLOCK_SIZE
#define BLKIO_FORTH_BLOCK_SIZE 1024u
#endif
/* Error codes (negative = error) */
enum {
BLKIO_OK = 0,
BLKIO_EINVAL = -1,
BLKIO_ENOSUP = -2,
BLKIO_EIO = -3,
BLKIO_ENOSPACE = -4,
BLKIO_ECLOSED = -5
};
/* Forward decl */
struct blkio_dev;
/* Open parameters (generic) */
typedef struct {
uint32_t forth_block_size; /* 0 => BLKIO_FORTH_BLOCK_SIZE */
uint32_t total_blocks; /* number of Forth blocks; FILE may derive when 0 */
void *opaque; /* backend-specific */
} blkio_params_t;
/* Device info */
typedef struct {
uint32_t forth_block_size;
uint32_t total_blocks;
uint32_t phys_sector_size; /* best-effort; 0 if N/A */
uint64_t phys_size_bytes; /* best-effort; 0 if N/A */
uint8_t read_only;
} blkio_info_t;
/* Backend vtable */
typedef struct {
int (*open)(struct blkio_dev *dev, const blkio_params_t *p);
int (*close)(struct blkio_dev *dev);
int (*read)(struct blkio_dev *dev, uint32_t fblock, void *dst);
int (*write)(struct blkio_dev *dev, uint32_t fblock, const void *src);
int (*flush)(struct blkio_dev *dev);
int (*info)(struct blkio_dev *dev, blkio_info_t *out);
} blkio_vtable_t;
/* Device (public) */
typedef struct blkio_dev {
const blkio_vtable_t *vt;
uint32_t forth_block_size;
uint32_t total_blocks;
void *state; /* backend private */
uint8_t is_open;
} blkio_dev_t;
/* Core wrappers */
static inline int blkio_open(blkio_dev_t *dev, const blkio_vtable_t *vt, const blkio_params_t *p) {
if (!dev || !vt || !vt->open || !vt->close || !vt->read || !vt->write || !vt->flush || !vt->info)
return BLKIO_EINVAL;
dev->vt = vt;
dev->is_open = 0u;
dev->state = 0;
dev->forth_block_size = (p && p->forth_block_size) ? p->forth_block_size : BLKIO_FORTH_BLOCK_SIZE;
if (dev->forth_block_size == 0) return BLKIO_EINVAL;
dev->total_blocks = p ? p->total_blocks : 0u;
const int rc = vt->open(dev, p);
if (rc == BLKIO_OK) dev->is_open = 1u;
return rc;
}
static inline int blkio_close(blkio_dev_t *dev) {
if (!dev || !dev->is_open) return BLKIO_ECLOSED;
const int rc = dev->vt->close(dev);
dev->is_open = 0u;
return rc;
}
static inline int blkio_read(blkio_dev_t *dev, uint32_t fblock, void *dst) {
if (!dev || !dev->is_open || !dst) return BLKIO_EINVAL;
if (fblock >= dev->total_blocks) return BLKIO_EINVAL;
return dev->vt->read(dev, fblock, dst);
}
static inline int blkio_write(blkio_dev_t *dev, uint32_t fblock, const void *src) {
if (!dev || !dev->is_open || !src) return BLKIO_EINVAL;
if (fblock >= dev->total_blocks) return BLKIO_EINVAL;
return dev->vt->write(dev, fblock, src);
}
static inline int blkio_flush(blkio_dev_t *dev) {
if (!dev || !dev->is_open) return BLKIO_ECLOSED;
return dev->vt->flush(dev);
}
static inline int blkio_info(blkio_dev_t *dev, blkio_info_t *out) {
if (!dev || !dev->is_open || !out) return BLKIO_EINVAL;
const int rc = dev->vt->info(dev, out);
if (rc == BLKIO_OK) {
if (!out->forth_block_size) out->forth_block_size = dev->forth_block_size;
if (!out->total_blocks) out->total_blocks = dev->total_blocks;
}
return rc;
}
/* Utilities */
static inline void blkio_bzero(void *p, uint32_t fbs) {
uint8_t *q = (uint8_t *) p;
for (uint32_t i = 0; i < fbs; i++) q[i] = 0;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* STARFORTH_BLKIO_H */
+101
View File
@@ -0,0 +1,101 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STARFORTH_BLKIO_FACTORY_H
#define STARFORTH_BLKIO_FACTORY_H
/* -----------------------------------------------------------------------------
StarForth - Block I/O Factory (Public API)
Chooses FILE backend when a disk image path is provided; otherwise RAM.
No dynamic allocation; caller supplies backend state memory.
NOTE: This header avoids referencing blkio typedefs to prevent "unknown type"
errors when include order or local headers differ. We forward-declare only the
device struct here. The implementation includes "blkio.h".
----------------------------------------------------------------------------- */
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declaration; real definition is in blkio.h */
struct blkio_dev;
/**
* Open a block device using either a file-backed image (if disk_img_path is
* non-empty) or a RAM-backed buffer (fallback).
*
* Parameters:
* - dev : output device object (caller-allocated)
* - disk_img_path : path to raw image; if NULL/empty => RAM fallback
* - read_only : 1 = open read-only; 0 = read/write
* - total_blocks : FILE: 0 => derive from file size; >0 => size hint
* RAM : must match ram_blocks
* - fbs : forth block size in bytes (0 => default per blkio.h)
* - state_mem : caller-provided backend state buffer (opaque to caller)
* - state_len : size of state_mem in bytes
* - ram_base : RAM storage base pointer (RAM backend only)
* - ram_blocks : number of Forth blocks in ram_base (RAM backend only)
* - out_used_file : optional; set to 1 if FILE backend selected, else 0
*
* Returns:
* 0 on success; negative blkio error code on failure.
*/
int blkio_factory_open(struct blkio_dev *dev,
const char *disk_img_path,
uint8_t read_only,
uint32_t total_blocks,
uint32_t fbs,
void *state_mem,
size_t state_len,
uint8_t *ram_base,
uint32_t ram_blocks,
uint8_t *out_used_file);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* STARFORTH_BLKIO_FACTORY_H */
File diff suppressed because it is too large Load Diff
+107
View File
@@ -0,0 +1,107 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STARFORTH_CLI_H
#define STARFORTH_CLI_H
#include <stdint.h>
#include "log.h"
/**
* @brief Heartbeat logging modes for DoE experiments
*/
typedef enum {
HEARTBEAT_LOG_OFF = 0, /* No heartbeat output, only final summary */
HEARTBEAT_LOG_SUMMARY = 1, /* Bucket aggregates every N ticks */
HEARTBEAT_LOG_FULL = 2 /* Per-tick CSV output to hb/run-<id>.csv */
} HeartbeatLogMode;
/**
* @brief Configuration structure from command-line arguments
* Consolidates all parsed CLI options into a single, cleanly organized struct
*/
typedef struct
{
/* Test modes */
int run_tests;
int break_me;
int fail_fast;
/* Benchmark mode */
int benchmark;
int benchmark_iterations;
/* Design of Experiments mode */
int doe_experiment; /* 1 if --doe-experiment flag set, run harness once and collect metrics */
HeartbeatLogMode heartbeat_log_mode; /* off|summary|full for DoE time-series data */
/* REPL mode */
int script_mode; /* -s: silent/script mode (no prompts, no "ok" output) */
/* Logging */
LogLevel log_level;
int log_level_explicitly_set;
/* Block I/O */
const char* disk_img_path;
uint32_t ram_disk_mb;
/* Legacy flags (internal use) */
int run_tests_flag_observed;
} CLIConfig;
/**
* @brief Parse command-line arguments into CLIConfig
*
* @param argc Argument count
* @param argv Argument vector
* @return CLIConfig struct with parsed options, or exits on --version/--help
*/
CLIConfig cli_parse(int argc, char* argv[]);
/**
* @brief Print usage/help information
* @param program_name Name of the executable
*/
void cli_print_usage(const char* program_name);
#endif /* STARFORTH_CLI_H */
+240
View File
@@ -0,0 +1,240 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef COMPUDYNAMICS_H
#define COMPUDYNAMICS_H
#include <stdint.h>
/* ============================================================================
* Compudynamics: Generic Entity-Agnostic Physics Engine
* ============================================================================
*
* Four operational levels observe and adapt to their own execution history:
* - words (dictionary entries, driven by ssm_jacquard.c) -- LIVE
* - VMs (Tripod fleet, driven by capsule_vm_physics.c) -- reserved
* - blocks (Artemis block storage) -- reserved
* - messages (Hermes event routing) -- reserved
*
* This module provides the entity-agnostic machinery shared by all four:
* a deterministic regime classifier over an entity-ID touch history, and a
* generic UCB1 bandit over a caller-sized config space. "Entity-ID" means
* whatever the level touches -- word_id for words, vm_id for VMs, block
* LBN for blocks, message type for messages.
*
* Determinism is the entire point of this module. Every input is an
* execution count or an entity-ID sequence -- never a wall-clock timestamp,
* never a duration. Two architectures executing the same instruction
* sequence at different real speeds (e.g. QEMU/TCG amd64 vs aarch64) must
* produce byte-identical classifier output. This was violated once
* (ssm_jacquard.c's temporal_decay input, derived from a wall-clock-tainted
* decay slope) and broke cross-architecture dict_hash parity; this module
* exists so that mistake has nowhere to hide the second time.
*
* Word-level and VM-level are the only two levels with real, instantiated
* CDTuning constants today (CD_TUNING_WORD, CD_TUNING_VM). Only word-level
* is actually wired through this module (ssm_jacquard.c); VM-level's own
* fleet mechanism (capsule_vm_physics.c, VMFleetWindow) is a separate,
* already-validated, already-accepted design that legitimately depends on
* real elapsed time for its rate-recovery math (fleet_transfer_slope_q48)
* and is out of scope here. CD_TUNING_VM documents what this module's
* classifier-side parameters would be if VM-level regime classification
* were ever migrated onto it; its bandit-side fields are zeroed and
* unused because VM level has no config-space bandit today. Block and
* message levels have no Artemis/Hermes compudynamics implementation yet
* -- CD_TUNING_BLOCK and CD_TUNING_MESSAGE are deliberately not defined
* here rather than filled with invented numbers.
* ============================================================================
*/
/* Hard cap on how many recent entity-ID touches cd_classify_ids() will look
* at. Callers pass a shorter slice via count; this cap bounds the classifier's
* O(depth^2) worst case and the stack scratch space it uses internally. */
#define CD_MAX_CLASSIFY_DEPTH 64u
/* ============================================================================
* Deterministic Regime Classification
* ============================================================================
*/
typedef struct {
uint32_t diversity_q16; /* distinct IDs in window / window size, Q16 [0,65536] */
uint32_t volatility_q16; /* dispersion (coefficient of variation) of per-ID
* touch counts within the window, Q16, unclamped
* above 65536 is possible and meaningful (high CV) */
uint32_t locality_q16; /* fraction of touches that repeat an ID seen within
* the preceding locality_lookback touches, Q16 [0,65536] */
} CDRegimeMetrics;
/**
* @brief Classify a recent entity-ID touch sequence into diversity/volatility/
* locality, purely from execution counts -- no wall-clock input anywhere.
*
* @param ids Recent entity IDs, oldest first, chronological order
* @param count Number of valid entries in ids (clamped internally
* to CD_MAX_CLASSIFY_DEPTH)
* @param locality_lookback How many preceding touches count as "recent" for
* the locality measure (clamped to count)
* @return Classified regime metrics; all-zero if count == 0
*/
CDRegimeMetrics cd_classify_ids(const uint32_t *ids, uint32_t count,
uint32_t locality_lookback);
/* ============================================================================
* Per-Level Tuning Knobs
* ============================================================================
*/
typedef struct {
/* --- Classifier knobs (used by cd_classify_ids callers) --- */
uint32_t id_window_depth; /* touches to classify over, <= CD_MAX_CLASSIFY_DEPTH */
uint32_t locality_lookback; /* recurrence lookback within id_window_depth */
uint32_t diversity_high_threshold_q16;
uint32_t volatility_high_threshold_q16;
uint32_t locality_high_threshold_q16;
/* --- Bandit knobs (used by cd_config_table_*); 0 where the level has
* no config-space bandit (e.g. VM level today -- see file header) --- */
uint32_t num_configs; /* size of the config space, e.g. 128 */
uint32_t num_regimes; /* size of the regime space, e.g. 8 */
uint32_t score_max;
uint32_t score_min;
uint32_t score_decay_factor_q16; /* per-tick exponential decay of benefit_score */
uint32_t ucb_k; /* UCB1 exploration coefficient */
uint32_t reward_gain; /* max per-tick score delta magnitude */
uint32_t joint_weight_q16; /* weight of window/locality joint-convergence
* signal in the combined reward, Q16 */
uint32_t anova_weight_q16; /* weight of the caller-supplied stability
* signal (e.g. ANOVA early-exit) in the
* combined reward, Q16 */
} CDTuning;
/* Tuning knobs are returned by value, not exposed as addressable globals.
* This freestanding kernel's boot-time loader does not reliably relocate
* the address of an extern const aggregate referenced from a different
* translation unit (confirmed by direct QEMU/gdb-style fault tracing:
* &CD_TUNING_WORD-style access faulted on an unrelocated pointer, while
* cross-TU function calls -- including struct-return-by-value, which
* uses a caller-local hidden pointer, never a global's address --
* worked correctly). Every existing scalar tunable elsewhere in this
* codebase already avoids this by being a #define immediate rather than
* a referenced global; these accessors are the aggregate-typed
* equivalent of that same constraint. */
/* Word level (ssm_jacquard.c): 128 configs (7-bit L1-L7), 8 regimes
* (3-bit diversity/volatility/locality). Values match the constants
* ssm_jacquard.c/.h used before this module existed -- this is a lift,
* not a retune. */
CDTuning cd_tuning_word(void);
/* VM level (capsule_vm_physics.c): classifier-side parameters only, for a
* future migration off Hera's word-level regime proxy. Not consumed by
* any call site today -- see file header. Bandit fields are zero: VM
* level modulates a continuous multiplier (fleet_transfer_slope_q48)
* rather than selecting from a discrete config space. */
CDTuning cd_tuning_vm(void);
/* ============================================================================
* Generic UCB1 Config-Space Bandit
* ============================================================================
*
* Stratified by regime: each (regime, config) pair has its own benefit
* score and tick count, so the bandit learns "best config per regime"
* rather than one global best. One clock only: cd_config_table_tick()
* scores the currently-active config and reselects on every call -- no
* derived multi-tick batching unit exists anywhere in this mechanism.
* ============================================================================
*/
typedef struct {
uint8_t config_bits;
uint8_t has_prev; /* 1 once prev_window/prev_locality_q16 hold real data */
uint8_t _pad[2];
uint32_t benefit_score;
uint32_t tick_count;
uint32_t prev_window;
uint32_t prev_locality_q16;
} CDConfigEntry;
typedef struct {
CDConfigEntry *entries; /* num_configs entries, malloc'd */
uint32_t *regime_scores; /* num_regimes * num_configs, row-major [regime][config] */
uint32_t *regime_ticks; /* same shape as regime_scores */
uint32_t *total_regime_ticks; /* num_regimes entries */
uint32_t num_configs;
uint32_t num_regimes;
uint8_t current_config;
uint8_t current_regime;
} CDConfigTable;
/**
* @brief Allocate a config table sized for tuning->num_configs / num_regimes.
* @return 0 on success, -1 on malloc failure (table left zeroed, unusable)
*/
int cd_config_table_init(CDConfigTable *table, const CDTuning *tuning);
/**
* @brief Free all memory owned by a config table. Safe on a zeroed table.
*/
void cd_config_table_free(CDConfigTable *table);
/**
* @brief Seed every (regime, config) score with initial_scores[config], and
* set the starting active config to initial_config.
* @param initial_scores Array of tuning->num_configs initial benefit scores
*/
void cd_config_table_seed(CDConfigTable *table, const CDTuning *tuning,
const uint32_t *initial_scores, uint8_t initial_config);
/**
* @brief Score the currently-active config from this tick's outcome and
* UCB1-reselect this tick's config, for the given regime.
*
* Combined reward = joint_weight * window/locality-convergence-stability
* + anova_weight * anova_stability_q16
* Joint-convergence is skipped (falls back to ANOVA-only) on a config's
* first tick, or when use_joint_convergence is false (the caller's config
* bits don't include loops whose convergence this signal is meant to
* track -- word level's L5/L6, see ssm_jacquard.c).
*
* @param table Config table (must be initialised)
* @param tuning Tuning knobs matching this table's sizing
* @param regime Current regime index, < tuning->num_regimes
* @param anova_stability_q16 Caller-supplied stability signal, Q16 [0,65536]
* @param use_joint_convergence Whether to include the window/locality signal
* @param current_window Caller's current window-width metric
* @param current_locality_q16 Caller's current locality_q16 from cd_classify_ids
* @return The newly-selected config's config_bits
*/
uint8_t cd_config_table_tick(CDConfigTable *table, const CDTuning *tuning,
uint8_t regime, uint32_t anova_stability_q16,
int use_joint_convergence,
uint32_t current_window, uint32_t current_locality_q16);
/**
* @brief Force the table onto an externally-chosen config (as if UCB1 had
* picked it). One-tick nudge, not a hold -- see ssm_l8_force_config().
*/
void cd_config_table_force(CDConfigTable *table, uint8_t config_idx);
#endif /* COMPUDYNAMICS_H */
+106
View File
@@ -0,0 +1,106 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
*** StarForth ***
dictionary_heat_optimization.h - Phase 2: Heat-Aware Dictionary Lookup
Inference-driven optimizations for dictionary lookup based on execution heat
patterns from the Rolling Window of Truth:
1. Heat percentile thresholds (25th, 50th, 75th)
2. Bucket reorganization by co-execution patterns
3. Heat-aware lookup strategy (search hot words first)
*/
#ifndef DICTIONARY_HEAT_OPTIMIZATION_H
#define DICTIONARY_HEAT_OPTIMIZATION_H
#include "vm.h"
/**
* @brief Calculate heat percentile thresholds for all words in dictionary
*
* Computes 25th, 50th, 75th percentiles of execution_heat across all
* dictionary entries. Used to partition lookup search order.
*/
void dict_update_heat_percentiles(VM *vm);
/**
* @brief Reorganize dictionary buckets by inference-driven priorities
*
* Uses rolling window co-execution patterns to reorder words within buckets.
* Hot/frequently co-executing words are placed first for faster lookup.
*/
void dict_reorganize_buckets_by_heat(VM *vm);
/**
* @brief Find word with heat-aware search strategy
*
* Instead of newest-first, searches buckets in order:
* 1. Top 25% by heat (likely hits)
* 2. Middle 50% by heat
* 3. Bottom 25% (rarely executed)
*/
DictEntry *dict_find_word_heat_aware(VM *vm, const char *name, size_t len);
/**
* @brief Periodically reoptimize dictionary based on latest heat patterns
*
* Called every ~1 second or every N executions to adapt lookup strategy
* to current workload patterns from rolling window.
*/
void dict_adaptive_optimization_pass(VM *vm);
/* Frequency-class (fc) buckets — shared between dictionary_management.c and
dictionary_heat_optimization.c. Declared here once to give LTO a single
canonical type definition and avoid -Werror=lto-type-mismatch. */
#ifndef SF_FC_BUCKETS
#define SF_FC_BUCKETS 256
#endif
extern DictEntry **sf_fc_list[SF_FC_BUCKETS];
extern size_t sf_fc_count[SF_FC_BUCKETS];
extern size_t sf_fc_cap[SF_FC_BUCKETS];
#endif /* DICTIONARY_HEAT_OPTIMIZATION_H */
+88
View File
@@ -0,0 +1,88 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef DICTIONARY_MANAGEMENT_H
#define DICTIONARY_MANAGEMENT_H
#include "vm.h" /* For VM type and word_func_t */
/**
* @brief Initialize the Forth dictionary
*
* @param vm Pointer to the virtual machine instance
*
* Initializes all dictionary structures and prepares them for use.
* Must be called before any other dictionary operations.
*/
void dictionary_init(VM * vm);
/**
* @brief Register a new word in the dictionary
*
* @param vm Pointer to the virtual machine instance
* @param name Name of the word to register
* @param func Function pointer to the word's implementation
*
* Adds a new word to the dictionary with the specified name and implementation.
*/
void dictionary_register(VM *vm, const char *name, word_func_t func);
/**
* @brief Look up a word in the dictionary by name
*
* @param vm Pointer to the virtual machine instance
* @param name Name of the word to look up
* @return word_func_t Function pointer to the word's implementation or NULL if not found
*/
word_func_t dictionary_lookup(VM *vm, const char *name);
/**
* @brief Clear the entire dictionary
*
* @param vm Pointer to the virtual machine instance
*
* Removes all words from the dictionary and frees associated memory.
* This is an optional operation that may be used during cleanup.
*/
void dictionary_clear(VM * vm);
#endif
+254
View File
@@ -0,0 +1,254 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file doe_metrics.h
* @brief Design of Experiments (DoE) metrics collection API
*
* Provides C-level programmatic access to VM metrics for physics-based experiments.
* Enables efficient in-process data collection without string parsing overhead.
*
* Usage:
* struct DoeMetrics metrics = metrics_from_vm(vm);
* metrics_write_csv_row(stdout, &metrics, run_number);
*/
#ifndef DOE_METRICS_H
#define DOE_METRICS_H
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include "vm.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Complete metrics snapshot for a single DoE run
*
* Represents all 35 metrics collected per test iteration, mirroring the CSV schema.
* All values extracted directly from VM structures (no string parsing).
*/
typedef struct {
/* === Metrics === */
uint32_t total_lookups; /* Total dictionary lookups during run */
/* === Cache Statistics === */
uint64_t cache_hits; /* Cache hits (if enabled) */
double cache_hit_percent; /* Hit percentage (0-100) */
uint64_t bucket_hits; /* Bucket hits after cache miss */
double bucket_hit_percent; /* Hit percentage (0-100) */
/* === Latency Metrics === */
int64_t cache_hit_latency_ns; /* Average cache hit latency (ns) */
int64_t cache_hit_stddev_ns; /* StdDev of cache hit latency */
int64_t bucket_search_latency_ns; /* Average bucket search latency (ns) */
int64_t bucket_search_stddev_ns; /* StdDev of bucket search latency */
/* === Pipelining Metrics (Loop #4) === */
uint64_t context_predictions_total; /* Total prefetch predictions */
uint64_t context_correct; /* Successful predictions */
double context_accuracy_percent; /* Accuracy percentage (0-100) */
uint64_t cache_promotions; /* Hotwords cache promotions */
uint64_t cache_demotions; /* Hotwords cache demotions */
/* === Rolling Window Metrics (Loop #2) === */
double window_diversity_percent; /* Window pattern diversity (0-100) */
uint32_t window_final_size_bytes; /* Final rolling window size */
uint32_t rolling_window_width; /* Width of rolling window (effective/adaptive) */
uint32_t actual_window_size; /* Ring buffer fill level: min(total_executions, ROLLING_WINDOW_SIZE) */
uint64_t total_executions; /* Words recorded in window */
uint64_t window_variance_q48; /* Pattern variance (Q48.16) */
/* === Heat Dynamics (Loop #1 & #3) === */
double decay_slope; /* Decay rate slope */
uint64_t total_heat; /* Aggregate execution heat */
uint64_t hot_word_count; /* Words above heat threshold */
uint64_t stale_word_count; /* Words with decaying heat */
double stale_word_ratio; /* Stale words / total words */
double avg_word_heat; /* Average execution heat */
/* === Heartbeat & Timing (Loop #7) === */
uint64_t tick_count; /* Total heartbeat ticks elapsed */
uint64_t tick_target_ns; /* Current tick interval (adaptive) */
uint64_t inference_run_count; /* Times inference engine invoked */
uint64_t early_exit_count; /* ANOVA early-exits (variance stable) */
/* === Window & Decay Inference (Loop #5 & #6) === */
double prefetch_accuracy_percent; /* Speculative prefetch success rate (0-100) */
uint64_t prefetch_attempts; /* Total speculative prefetch attempts */
uint64_t prefetch_hits; /* Successful prefetch hits */
uint64_t window_tuning_checks; /* Number of times window was tuned */
uint32_t final_effective_window_size; /* Final window size after tuning */
/* === Performance === */
int64_t vm_workload_duration_ns_q48; /* VM workload duration (Q48.16, nanoseconds) */
uint64_t total_runtime_ms; /* Total execution time (ms) */
uint64_t words_executed; /* Total word executions */
uint64_t dictionary_lookups; /* Dictionary search operations */
uint64_t memory_allocated_bytes; /* Total memory allocated */
double speedup_vs_baseline; /* Speedup ratio vs baseline */
/* === Statistical === */
double ci_lower_95; /* 95% confidence interval lower */
double ci_upper_95; /* 95% confidence interval upper */
/* === System State Deltas === */
int64_t cpu_temp_delta_c_q48; /* CPU temp change during run (Q48.16, °C) */
int64_t cpu_freq_delta_mhz_q48; /* CPU freq change during run (Q48.16, MHz) */
/* === Tuning Knobs === */
uint32_t decay_rate_q16; /* Decay rate (Q16 fixed-point) */
uint32_t decay_min_interval_ns; /* Min decay interval (ns) */
uint32_t rolling_window_size; /* Rolling window size */
uint32_t adaptive_shrink_rate; /* Shrink rate percentage */
uint32_t heat_cache_demotion_threshold; /* Demotion threshold */
/* === Loop Enable Flags (2^7 factorial) === */
int enable_loop_1_heat_tracking; /* Loop #1: Execution heat tracking */
int enable_loop_2_rolling_window; /* Loop #2: Rolling window history */
int enable_loop_3_linear_decay; /* Loop #3: Linear decay */
int enable_loop_4_pipelining; /* Loop #4: Pipelining metrics */
int enable_loop_5_window_inference; /* Loop #5: Window width inference */
int enable_loop_6_decay_inference; /* Loop #6: Decay slope inference */
int enable_loop_7_adaptive_heartrate; /* Loop #7: Adaptive heartrate */
/* === Legacy Configuration === */
int enable_hotwords_cache; /* 1 if cache enabled, 0 otherwise */
int enable_pipelining; /* 1 if pipelining enabled, 0 otherwise */
} DoeMetrics;
/**
* @brief Extract complete metrics snapshot from VM
*
* Collects all metrics from current VM state after a test harness run.
* Workload duration and CPU deltas must be supplied by caller.
*
* @param vm Pointer to Forth VM instance
* @param workload_duration_ns Actual VM workload execution time (nanoseconds)
* @param cpu_temp_delta_c CPU temperature change during run (°C)
* @param cpu_freq_delta_mhz CPU frequency change during run (MHz)
* @return Populated metrics structure (timestamp filled in)
*/
DoeMetrics metrics_from_vm(VM *vm, uint64_t workload_duration_ns,
int32_t cpu_temp_delta_c, int32_t cpu_freq_delta_mhz);
/**
* @brief Write CSV header row
*
* Writes the 35-column CSV header to output stream.
*
* @param out Output file stream
*/
void metrics_write_csv_header(FILE *out);
/**
* @brief Write metrics as CSV row
*
* Writes a single run's metrics as comma-separated values.
*
* @param out Output file stream
* @param metrics Metrics structure to write
*/
void metrics_write_csv_row(FILE *out, const DoeMetrics *metrics);
/**
* @brief Write reduced James Law CSV row (20 columns)
*
* Outputs only the subset of metrics needed for the James Law validation experiment.
* This matches the header format in run_window_sweep.sh (minus the 5 script-prepended columns).
*
* @param out Output file stream
* @param metrics Metrics structure to write
* @param vm VM instance (for heartbeat bucket aggregates and L8 mode)
*/
void metrics_write_james_law_csv_row(FILE *out, const DoeMetrics *metrics, VM *vm);
/**
* @brief Print metrics as human-readable text
*
* Outputs metrics in formatted text for debugging/verification.
*
* @param out Output file stream
* @param metrics Metrics structure to print
*/
void metrics_print_text(FILE *out, const DoeMetrics *metrics);
/**
* @brief Get current CPU temperature (Celsius)
*
* Reads /sys/class/thermal/thermal_zone0/temp on Linux,
* returns 0 if unavailable.
*
* @return Temperature in °C, or 0 if unable to read
*/
int32_t metrics_get_cpu_temp_c(void);
/**
* @brief Get current CPU frequency (MHz)
*
* Tries multiple sources:
* 1. /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
* 2. /proc/cpuinfo
* Returns 0 if unavailable.
*
* @return Frequency in MHz, or 0 if unable to read
*/
int32_t metrics_get_cpu_freq_mhz(void);
/**
* @brief Get current timestamp as ISO 8601 string
*
* Format: "YYYY-MM-DDTHH:MM:SS"
*
* @param buf Buffer to write timestamp (minimum 32 bytes)
* @param bufsize Size of buffer
*/
void metrics_get_timestamp(char *buf, size_t bufsize);
#ifdef __cplusplus
}
#endif
#endif /* DOE_METRICS_H */
+263
View File
@@ -0,0 +1,263 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef INFERENCE_ENGINE_H
#define INFERENCE_ENGINE_H
#include <stdint.h>
#include <stddef.h>
#include "vm.h" /* For RollingWindowOfTruth, VM structure */
#include "q48_16.h" /* For Q48.16 fixed-point math */
/* ============================================================================
* OpAmp Model: Inference Engine Architecture
* ============================================================================
*
* The inference engine unifies all VM adaptive tuning into a single loop:
*
* Rolling Window of Truth (execution_heat trajectory, metrics)
* ↓
* [Inference Engine]
* ├─ ANOVA Early-Exit: Check if variance stable
* ├─ Window Width Inference: Variance inflection detection
* ├─ Decay Slope Inference: Closed-form linear regression
* └─ Diagnostics: Fit quality, variance metrics
* ↓
* Tuning Outputs (adaptive_window_width, adaptive_decay_slope)
* ↓
* [Apply to VM]
* ↓
* [System Adapts]
* ↓
* [Feedback Loop Repeats]
*
* Key Design Principles:
* - Q48.16 math only (no floating-point)
* - ANOVA early-exit for efficiency (5% variance threshold)
* - Closed-form algorithms (deterministic, fast)
* - Observable diagnostics (RStudio dashboard feed)
*/
/* ============================================================================
* Input Data Structure: Metrics snapshot + window context
* ============================================================================
*/
typedef struct {
VM *vm; /* Owning VM (for dictionary heat snapshots) */
/* === Window Context === */
RollingWindowOfTruth *window; /* Pointer to window of truth */
uint64_t trajectory_length; /* Number of heat entries to analyze */
/* === Current Metrics Snapshot === */
uint64_t prefetch_hits; /* Successful prefetch predictions */
uint64_t prefetch_attempts; /* Total prefetch attempts */
uint64_t hot_word_count; /* Words above execution_heat threshold */
uint64_t stale_word_count; /* Words with execution_heat in low range */
uint64_t total_heat; /* Sum of all execution_heat values */
uint32_t word_count; /* Total dictionary entries */
/* === Baseline (For Trending) === */
uint64_t last_total_heat; /* Total heat from previous check */
uint64_t last_stale_count; /* Stale count from previous check */
} InferenceInputs;
/* ============================================================================
* Output Data Structure: Tuning parameters + diagnostics
* ============================================================================
*/
struct InferenceOutputs {
/* === Tuning Outputs (Apply to VM) === */
uint32_t adaptive_window_width; /* Inferred optimal window size (from variance inflection) */
uint64_t adaptive_decay_slope; /* Inferred decay slope in Q48.16 (from regression) */
/* === Diagnostics (RStudio Dashboard Feed) === */
uint64_t window_variance_q48; /* Variance of heat across window in Q48.16 */
uint64_t slope_fit_quality_q48; /* R² or residual metric in Q48.16 (0.0 to 1.0) */
/* === Status Tracking === */
uint32_t early_exited; /* 1 if ANOVA check skipped full inference, 0 if full run */
uint64_t last_check_tick; /* Timestamp of last full inference (for monitoring) */
};
/* ============================================================================
* Main API: Run Inference Engine
* ============================================================================
*
* Single entry point that handles:
* 1. ANOVA early-exit (check variance stability)
* 2. Full inference (if variance changed significantly)
* 3. Update tuning outputs
*
* Thread-Safety: Safe for synchronous calls from vm_tick()
* (No shared state written; outputs struct is caller-allocated)
*/
/**
* @brief Run adaptive inference engine on window data
*
* High-level flow:
* 1. ANOVA Check: Is variance delta < 5%?
* - YES: Return cached outputs immediately (cost: ~100 cycles)
* - NO: Continue to full inference
*
* 2. Extract trajectory: Fresh execution_heat snapshot from dictionary
*
* 3. Window Width Inference:
* - Compute variance across entire window
* - Detect inflection point (where d(variance)/d(size) → 0)
* - Return optimal window size
*
* 4. Decay Slope Inference:
* - Transform trajectory to log space (ln(heat[t]))
* - Fit linear regression: ln(heat) = a - slope*t
* - Extract slope coefficient in Q48.16
*
* 5. Diagnostics:
* - Compute fit quality (R² or residual)
* - Store variance metric for next early-exit check
*
* @param inputs Snapshot of window + metrics (caller-provided)
* @param outputs Tuning parameters + diagnostics (caller-provided, will be updated)
*
* @return void (results_run_01_2025_12_08 in outputs struct)
*
* Preconditions:
* - inputs != NULL
* - outputs != NULL
* - inputs->window != NULL
* - inputs->window->is_warm == 1 (window has enough data)
* - inputs->trajectory_length > 1
*
* Side Effects:
* - Modifies outputs struct (caller must preserve if caching)
* - Allocates temporary trajectory buffer (freed on return)
*/
void inference_engine_run(InferenceInputs *inputs, InferenceOutputs *outputs);
/* ============================================================================
* Configuration Constants (In vm.h, but referenced here)
* ============================================================================
*
* User-tunable via Makefile:
*
* #define HEARTBEAT_INFERENCE_FREQUENCY 5000
* - Ticks between full inference runs
* - Decreasing = faster response, more CPU
* - Increasing = slower response, less CPU
*
* #define VARIANCE_SIGNIFICANCE_THRESHOLD 5
* - Percentage (0-100) at which variance change triggers re-inference
* - Default: 5% (skip inference if variance changed < 5%)
* - Decreasing = more frequent re-inference (conservative)
* - Increasing = less frequent re-inference (aggressive)
*
* #define ADAPTIVE_MIN_WINDOW_SIZE 256
* - Minimum effective_window_size (never shrink below this)
* - Ensures minimum statistical validity
* - Increasing = higher overhead, more accuracy
*/
/* ============================================================================
* Helper Functions (For Testing / Diagnostics)
* ============================================================================
*/
/*
* @brief Pretty-print inference outputs for logging
*
* Format: "window_width=XXX variance_q48=YYYY slope_q48=ZZZZ fit_quality=WWWW"
*
* @param outputs Inference outputs struct
* @return Pointer to static string (valid until next call)
*/
const char* inference_outputs_to_string(const InferenceOutputs *outputs);
/*
* @brief Validate inference outputs for sanity
*
* Checks:
* - window_width is within [ADAPTIVE_MIN_WINDOW_SIZE, ROLLING_WINDOW_SIZE]
* - slope_q48 is reasonable (between 0.001 and 100 in Q48.16)
* - variance and fit_quality are between 0.0 and 1.0 in Q48.16
*
* @param outputs Inference outputs to validate
* @return 1 if valid, 0 if suspicious
*/
int inference_outputs_validate(const InferenceOutputs *outputs);
/* ============================================================================
* Internal Functions (Exposed for Unit Testing)
* ============================================================================
*/
/*
* @brief Compute variance of heat data in Q48.16 format
*
* @param heat_data Array of heat values
* @param length Number of elements in array
* @return Variance in Q48.16 format
*/
q48_16_t compute_variance_q48(const uint64_t *heat_data, uint64_t length);
/*
* @brief Find variance inflection point for optimal window width
*
* @param heat_data Array of heat values
* @param trajectory_length Total trajectory length
* @param full_variance Variance of full trajectory
* @return Optimal window width
*/
uint32_t find_variance_inflection(const uint64_t *heat_data, uint64_t trajectory_length, q48_16_t full_variance);
/*
* @brief Infer decay slope from heat trajectory using linear regression
*
* @param heat_data Array of heat values
* @param length Number of elements
* @return Decay slope in Q48.16 format
*/
uint64_t infer_decay_slope_q48(const uint64_t *heat_data, uint64_t length);
#endif /* INFERENCE_ENGINE_H */
+80
View File
@@ -0,0 +1,80 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef IO_H
#define IO_H
#include <stdint.h>
#include "vm.h"
/* BLOCK_SIZE is defined in vm.h */
/** @brief Total number of blocks available */
#define BLOCK_COUNT 1024
/** @brief Total memory size in bytes */
#define MEMORY_SIZE (BLOCK_SIZE * BLOCK_COUNT)
/*
* @brief Initialize the I/O subsystem
* @param vm Pointer to the virtual machine instance
*/
void io_init(VM * vm);
/**
* @brief Read a block from storage
* @param vm Pointer to the virtual machine instance
* @param block_num Block number to read
* @param buffer Buffer to store the read data
* @return 0 on success, non-zero on failure
*/
int io_read_block(VM *vm, int block_num, unsigned char *buffer);
/*
* @brief Write a block to storage
* @param vm Pointer to the virtual machine instance
* @param block_num Block number to write
* @param buffer Buffer containing data to write
* @return 0 on success, non-zero on failure
*/
int io_write_block(VM *vm, int block_num, const unsigned char *buffer);
#endif /* IO_H */
+120
View File
@@ -0,0 +1,120 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef LOG_H
#define LOG_H
/* Maximum log line size for persistent logging */
/* Renamed from LOG_LINE_MAX: vm.h owns that name for the persistent
* block-log line width (64, unrelated concept). This is the in-memory log
* message-formatting line length; keeping a distinct name removes the
* include-order collision that forced a fragile "vm.h before log.h"
* convention across the kernel (kernel_main.c/shim.c/capsule_birth.c). */
#ifndef LOG_MSG_LINE_MAX
#define LOG_MSG_LINE_MAX 256
#endif
/* Forward declaration */
struct VM;
/**
* @brief Logging level enumeration
*
* Defines the available logging levels in order of increasing verbosity.
*/
typedef enum {
LOG_NONE = -1, /**< Completely disable all logging */
LOG_ERROR = 0, /**< Error messages only */
LOG_WARN, /**< Warning and error messages */
LOG_INFO, /**< Informational, warning and error messages */
LOG_TEST, /**< Test results_run_01_2025_12_08 and all previous levels */
LOG_DEBUG /**< Debug messages and all previous levels */
} LogLevel;
/**
* @brief Test result type enumeration
*
* Defines the possible outcomes of test execution.
*/
typedef enum {
TEST_PASS = 0, /**< Test completed successfully */
TEST_FAIL, /**< Test failed */
TEST_SKIP, /**< Test was skipped */
TEST_ERROR /**< Test encountered an error during execution */
} TestResult;
/**
* @brief Set the global logging level
* @param level The new logging level to set
* @note Default level is LOG_INFO
*/
void log_set_level(LogLevel level);
/**
* @brief Get the current logging level
* @return The current logging level
*/
LogLevel log_get_level(void);
/**
* @brief Log a formatted message at the specified level
* @param level The logging level for this message
* @param fmt Printf-style format string
* @param ... Variable arguments for format string
*/
void log_message(LogLevel level, const char *fmt, ...);
/**
* @brief Log a test result with colored output
* @param word_name Name of the word being tested
* @param result Result of the test execution
*/
void log_test_result(const char *word_name, TestResult result);
/**
* @brief Set the VM instance for persistent logging
* @param vm VM instance to use for persistent logging (NULL to disable)
*/
void log_set_vm(struct VM *vm);
#endif /* LOG_H */
+91
View File
@@ -0,0 +1,91 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* math_portable.h
*
* Portable C99 math functions in Q48.16 64-bit fixed-point format.
* Suitable for embedded environments with no libm
* (HISTORICAL: also L4Re, through mid-2026; removed as an active target).
* All arithmetic is integer-only for maximum performance.
*
* Q48.16 Format:
* - 48-bit signed integer + 16-bit fractional part
* - Precision: 2^-16 ≈ 0.0000153 (nanoseconds)
* - Range: ±140 trillion ns (≈ 4.4 years)
*
* Functions:
* sqrt_q48(x) - Square root of Q48.16 value via Newton-Raphson
* erf_q48(x) - Error function of Q48.16 value (dimensionless)
*/
#ifndef MATH_PORTABLE_H
#define MATH_PORTABLE_H
#include <stdint.h>
#define Q48_SCALE (1LL << 16) /* 65536 */
/**
* Square root in Q48.16 fixed-point
* Input: x in Q48.16 format
* Output: sqrt(x) in Q48.16 format
* Uses Newton-Raphson: x_{n+1} = (x_n + a/x_n) / 2
* Converges in ~10-15 iterations
* Returns 0 for negative inputs (guard against domain error)
*/
int64_t sqrt_q48(int64_t x);
/**
* Error function in Q48.16 fixed-point
* Input: x in Q48.16 format (dimensionless Z-score)
* Output: erf(x) in Q48.16 format (range: -Q48_SCALE to +Q48_SCALE)
* Uses Abramowitz & Stegun approximation (7.1.26)
* Maximum error: 1.5e-7 relative to floating-point erf
* Properties:
* - erf(0) = 0
* - erf(-x) = -erf(x) (odd function)
* - erf(x) approaches ±Q48_SCALE for large |x|
*/
int64_t erf_q48(int64_t x);
#endif /* MATH_PORTABLE_H */
+68
View File
@@ -0,0 +1,68 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file memory_management.h
* @brief Memory management functions for the StarForth virtual machine
*
* This file contains functions for managing memory allocation and alignment
* in the StarForth virtual machine implementation.
*/
#ifndef VM_MEMORY_H
#define VM_MEMORY_H
#include "vm.h"
/*
* @brief Allocates memory in the virtual machine's memory space
* @param vm Pointer to the virtual machine instance
* @param bytes Number of bytes to allocate
* @return Pointer to the allocated memory or NULL if allocation fails
*/
void *vm_allot(VM *vm, size_t bytes);
/*
* @brief Aligns the virtual machine's memory pointer to the next word boundary
* @param vm Pointer to the virtual machine instance
*/
void vm_align(VM * vm);
#endif
+92
View File
@@ -0,0 +1,92 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STARFORTH_PHYSICS_EXECUTION_HOOKS_H
#define STARFORTH_PHYSICS_EXECUTION_HOOKS_H
/*
* physics_execution_hooks.h - Clean abstraction for physics-driven execution hooks
*
* Purpose: Hide ALL physics machinery behind two simple function calls.
* The VM execution loop calls these; it doesn't know or care about:
* - Heat tracking
* - Decay models
* - Rolling window
* - Pipelining metrics
* - Hotwords cache
* - Profiling
*
* This keeps vm.c clean and focused on execution semantics.
*/
#include "vm.h"
/*
* Call BEFORE executing a word.
* Handles: decay, heat increment, rolling window, pipelining speculation check.
*
* @param vm The VM instance
* @param word The word about to execute
* @param prev The previously executed word (NULL if first in sequence)
*/
void physics_pre_execute(VM* vm, DictEntry* word, DictEntry* prev);
/*
* Call AFTER executing a word.
* Handles: physics touch, profiler exit, DoE counter, heartbeat check.
*
* @param vm The VM instance
* @param word The word that just executed
*/
void physics_post_execute(VM* vm, DictEntry* word);
/*
* Call when looking up a word (outer interpreter).
* Handles: decay + heat for lookup path (not inner loop).
*
* @param vm The VM instance
* @param entry The word found
* @param canon Canonical dictionary entry (may differ from entry)
*/
void physics_on_lookup(VM* vm, DictEntry* entry, DictEntry* canon);
#endif /* STARFORTH_PHYSICS_EXECUTION_HOOKS_H */
File diff suppressed because it is too large Load Diff
+111
View File
@@ -0,0 +1,111 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
*** StarForth ***
physics_metadata.h - Physics metadata helpers for dictionary entries
Phase 1 implements lightweight thermodynamic signals that inform scheduling
and storage placement while keeping the runtime overhead minimal.
*/
#ifndef STARFORTH_PHYSICS_METADATA_H
#define STARFORTH_PHYSICS_METADATA_H
#include <stdint.h>
#include "vm.h"
/* L8 FINAL INTEGRATION: L1 heat tracking always-on */
/* ============================================================================
* INTENT: Atomic heat increment for FL1 feedback loop
* FL1: Heat accumulation - called on every word execution by inner interpreter
* WHY: Atomic operations prevent race conditions when multiple execution paths
* (e.g., heartbeat thread + main interpreter) touch execution_heat
* RELAXED memory order is sufficient (no ordering dependencies)
* ============================================================================ */
static inline void physics_execution_heat_increment(DictEntry *entry)
{
if (!entry) return;
#if defined(__GNUC__)
__atomic_fetch_add(&entry->execution_heat, 1, __ATOMIC_RELAXED);
#else
entry->execution_heat++;
#endif
}
static inline cell_t physics_execution_heat_load(const DictEntry *entry)
{
if (!entry) return 0;
#if defined(__GNUC__)
return __atomic_load_n(&entry->execution_heat, __ATOMIC_RELAXED);
#else
return entry->execution_heat;
#endif
}
static inline uint64_t physics_decay_slope_load(const VM *vm)
{
#if defined(__GNUC__)
return __atomic_load_n(&vm->decay_slope_q48, __ATOMIC_RELAXED);
#else
return vm->decay_slope_q48;
#endif
}
void physics_metadata_init(DictEntry *entry, uint32_t header_bytes);
void physics_metadata_set_mass(DictEntry *entry, uint32_t total_bytes);
void physics_metadata_touch(DictEntry *entry, cell_t execution_heat, uint64_t now_ns);
void physics_metadata_refresh_state(DictEntry * entry);
void physics_metadata_record_latency(DictEntry *entry, uint64_t sample_ns);
void physics_metadata_apply_seed(DictEntry * entry);
/* L8 FINAL INTEGRATION: L3 linear decay always-on */
void physics_metadata_apply_linear_decay(DictEntry *entry, uint64_t elapsed_ticks, VM *vm);
#endif /* STARFORTH_PHYSICS_METADATA_H */
File diff suppressed because it is too large Load Diff
+215
View File
@@ -0,0 +1,215 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
*** StarForth ***
physics_runtime.h - Phase 1 physics runtime services
Provides host snapshot shims (POSIX + L4Re) and analytics heap scaffolding
for physics-aware scheduling. The interface is intentionally lightweight so
future governance-approved modules can extend it without ABI churn.
============================================================================
IMPORTANT SYNC NOTE (projects using git hooks / governance mirror):
• If you change HOLA protocol fields, magic, or version numbers below, also
update the governance export docs so the L4Re mirror stays aligned.
• Daemons touching this header can throw a warning when HOLA_PROTOCOL_* or
HOLA_SHARED_MAGIC change to catch accidental ABI drifts early.
• Reference: docs/src/internal/GOVERNANCE_EXPORT_NOTES.adoc
============================================================================
*/
#ifndef STARFORTH_PHYSICS_RUNTIME_H
#define STARFORTH_PHYSICS_RUNTIME_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Default analytics heap size (10 MiB) */
#define PHYSICS_ANALYTICS_DEFAULT_HEAP_BYTES (10u * 1024u * 1024u)
/** Magic tag for HOLA analytics heap headers ('HOLA') */
#define HOLA_SHARED_MAGIC 0x484f4c41u
/** HOLA protocol version (major.minor) */
#define HOLA_PROTOCOL_MAJOR 0x0001u
#define HOLA_PROTOCOL_MINOR 0x0000u
/** Host backend identifier */
typedef enum physics_host_backend {
PHYSICS_HOST_BACKEND_POSIX = 0,
PHYSICS_HOST_BACKEND_L4RE = 1, /* HISTORICAL: no backend sets this anymore; L4Re removed as an active target. Value kept stable for the HOLA analytics data format. */
PHYSICS_HOST_BACKEND_FAKE = 2
} physics_host_backend_t;
/** Analytics channel ids */
#define PHYSICS_ANALYTICS_CHANNEL_HOST_SNAPSHOT 0x00000002u
/** Host snapshot flag bits */
#define PHYSICS_HOST_FLAG_PSI 0x0001u
#define PHYSICS_HOST_FLAG_CGROUP 0x0002u
#define PHYSICS_HOST_FLAG_CPU_STAT 0x0004u
/**
* @brief Snapshot of scheduler-adjacent host signals.
*
* Fields are intentionally fixed width to maximise portability and allow the
* governance repository to consume binary dumps without per-platform quirks.
*/
typedef struct physics_host_snapshot {
physics_host_backend_t backend; /**< Selected backend (POSIX/L4Re/other) */
uint32_t scheduler_policy; /**< OS-specific scheduler policy identifier */
uint32_t scheduler_priority; /**< Nominal thread priority */
uint32_t scheduler_quantum_ns; /**< Reported quantum in nanoseconds (0 if unknown) */
uint32_t runnable_threads; /**< Runnable entities on this CPU set (best effort) */
uint32_t cpu_count; /**< Online logical CPU count */
uint32_t load_avg_milli; /**< Smoothed load average (×1000) */
uint32_t flags; /**< Backend-specific flags */
uint32_t psi_cpu_some_avg10_milli; /**< CPU PSI some avg10 ×1000 */
uint32_t psi_cpu_some_avg60_milli; /**< CPU PSI some avg60 ×1000 */
uint32_t psi_cpu_some_avg300_milli; /**< CPU PSI some avg300 ×1000 */
uint32_t psi_cpu_full_avg10_milli; /**< CPU PSI full avg10 ×1000 */
uint32_t psi_cpu_full_avg60_milli; /**< CPU PSI full avg60 ×1000 */
uint32_t psi_cpu_full_avg300_milli; /**< CPU PSI full avg300 ×1000 */
uint32_t psi_io_some_avg10_milli; /**< IO PSI some avg10 ×1000 */
uint32_t psi_io_some_avg60_milli; /**< IO PSI some avg60 ×1000 */
uint32_t psi_io_some_avg300_milli; /**< IO PSI some avg300 ×1000 */
uint32_t psi_io_full_avg10_milli; /**< IO PSI full avg10 ×1000 */
uint32_t psi_io_full_avg60_milli; /**< IO PSI full avg60 ×1000 */
uint32_t psi_io_full_avg300_milli; /**< IO PSI full avg300 ×1000 */
uint32_t psi_mem_some_avg10_milli; /**< Memory PSI some avg10 ×1000 */
uint32_t psi_mem_some_avg60_milli; /**< Memory PSI some avg60 ×1000 */
uint32_t psi_mem_some_avg300_milli; /**< Memory PSI some avg300 ×1000 */
uint64_t monotonic_time_ns; /**< Monotonic clock reading */
uint64_t realtime_ns; /**< Wall-clock timestamp (0 if unavailable) */
uint64_t backend_seq; /**< Backend-provided sequence counter */
uint64_t cpu_total_jiffies; /**< /proc/stat total jiffies snapshot */
uint64_t cpu_idle_jiffies; /**< /proc/stat idle jiffies snapshot */
uint64_t cgroup_cpu_usage_us; /**< cgroup v2 cpu.stat usage_usec (0 if unavailable) */
uint64_t cgroup_memory_current_bytes; /**< cgroup v2 memory.current (0 if unavailable) */
} physics_host_snapshot_t;
/** Event header written into the analytics ring buffer. */
typedef struct physics_analytics_event_header {
uint32_t channel; /**< Logical channel identifier */
uint16_t payload_bytes; /**< Size of event payload */
uint16_t reserved; /**< Reserved for alignment */
uint64_t timestamp_ns; /**< Producer timestamp */
} physics_analytics_event_header_t;
/** Analytics heap header seen by both producer (VM) and consumer (HOLA). */
typedef struct physics_analytics_header {
uint32_t magic; /**< HOLA_SHARED_MAGIC */
uint16_t version_major; /**< Protocol major version */
uint16_t version_minor; /**< Protocol minor version */
uint32_t heap_bytes; /**< Total heap size */
uint32_t ring_offset; /**< Offset to event ring */
uint32_t ring_bytes; /**< Event ring length */
uint32_t summary_offset; /**< Offset to summary/scratch region */
uint32_t summary_bytes; /**< Summary region length */
uint32_t scratch_offset; /**< Offset to reserved scratch area */
uint32_t scratch_bytes; /**< Scratch area length */
uint64_t produce_seq; /**< Monotonic sequence for producers */
uint64_t consume_seq; /**< Consumer-visible sequence */
uint32_t write_offset; /**< Producer write cursor */
uint32_t read_offset; /**< Consumer read cursor */
uint32_t dropped_events; /**< Count of dropped events */
uint32_t flags; /**< Heap flags (see docs) */
} physics_analytics_header_t;
/** Simple view onto the analytics heap layout. */
typedef struct physics_analytics_heap {
uint8_t *base; /**< Base pointer (owned by runtime) */
size_t bytes; /**< Total bytes reserved */
physics_analytics_header_t *header; /**< Shared header */
uint8_t *ring; /**< Event ring base */
size_t ring_bytes; /**< Event ring span */
uint8_t *summary; /**< Summary/statistics region */
size_t summary_bytes; /**< Summary region span */
uint8_t *scratch; /**< Scratch/reserved region */
size_t scratch_bytes; /**< Scratch region span */
} physics_analytics_heap_t;
/*
* @brief Initialise physics runtime services.
* @param analytics_heap_bytes Desired heap size (0 -> default 10 MiB)
* @return 0 on success, -1 on failure
*/
int physics_runtime_init(size_t analytics_heap_bytes);
/**
* @brief Tear down physics runtime services and release heap storage.
*/
void physics_runtime_shutdown(void);
/*
* @brief Capture a host snapshot.
* @param out Output buffer
* @return 0 on success, -1 on failure
*/
int physics_host_snapshot(physics_host_snapshot_t *out);
/*
* @brief Publish an event into the analytics ring buffer.
* @param channel Logical event channel
* @param payload Pointer to payload bytes
* @param payload_bytes Payload length (<= ring size)
* @return 0 on success, -1 if the payload could not be enqueued
*/
int physics_analytics_publish_event(uint32_t channel, const void *payload, uint16_t payload_bytes);
/**
* @brief Retrieve the analytics heap descriptor.
* @return Pointer to heap descriptor (NULL if runtime not initialised)
*/
const physics_analytics_heap_t *physics_analytics_heap_info(void);
#ifdef __cplusplus
}
#endif
#endif /* STARFORTH_PHYSICS_RUNTIME_H */
+86
View File
@@ -0,0 +1,86 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STARFORTH_PLATFORM_ALLOC_H
#define STARFORTH_PLATFORM_ALLOC_H
/*
* platform_alloc.h - Portable memory allocation abstraction
*
* Host builds: Uses standard malloc/free
* Kernel builds: Uses static arena with bump allocator
*
* Usage:
* void* p = sf_malloc(size);
* sf_free(p);
* void* p2 = sf_calloc(count, size); // zero-initialized
*/
#include <stddef.h>
/*
* Allocate memory block of given size.
* Returns NULL on failure.
*/
void* sf_malloc(size_t size);
/*
* Allocate zero-initialized memory for array.
* Returns NULL on failure.
*/
void* sf_calloc(size_t count, size_t size);
/*
* Reallocate memory block to new size.
* Returns NULL on failure (original block unchanged).
*/
void* sf_realloc(void* ptr, size_t new_size);
/*
* Free previously allocated memory.
* Passing NULL is safe (no-op).
*/
void sf_free(void* ptr);
/*
* Initialize the allocator (required for kernel builds).
* Host builds: no-op.
* Kernel builds: sets up the static arena.
*
* Returns 0 on success, -1 on failure.
*/
int sf_alloc_init(void);
/*
* Get allocator statistics (for diagnostics).
*/
typedef struct sf_alloc_stats {
size_t total_bytes; /* Total arena size */
size_t used_bytes; /* Currently allocated */
size_t peak_bytes; /* High water mark */
size_t alloc_count; /* Number of allocations */
size_t free_count; /* Number of frees */
} sf_alloc_stats_t;
void sf_alloc_get_stats(sf_alloc_stats_t* stats);
#endif /* STARFORTH_PLATFORM_ALLOC_H */
+47
View File
@@ -0,0 +1,47 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* platform_io.h - Portable terminal-input-readiness check for StarForth
*
* One function, same shape as platform_lock.h/platform_time.h: a single
* portable declaration, implemented once per platform (POSIX select() on
* fd 0 for the hosted build, src/platform/linux/io.c; the kernel's own
* console/keyboard-event bridge for the freestanding build, shim.c).
* Backs the standard dictionary's ?TERMINAL word (io_words.c).
*/
#ifndef STARFORTH_PLATFORM_IO_H
#define STARFORTH_PLATFORM_IO_H
/**
* @brief Non-blocking check for whether a key/character is available to read.
*
* Must not block and must not consume the byte if one is found (a
* following KEY/getchar() must still return that same byte).
*
* @return 1 if input is ready, 0 otherwise
*/
int sf_terminal_ready(void);
#endif /* STARFORTH_PLATFORM_IO_H */
+71
View File
@@ -0,0 +1,71 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* platform_lock.h - Portable mutex abstraction for StarForth
*/
#ifndef STARFORTH_PLATFORM_LOCK_H
#define STARFORTH_PLATFORM_LOCK_H
/* HISTORICAL: this condition also included `|| defined(L4RE_TARGET)` --
* L4Re had no pthreads either, so it shared the spinlock path with
* STARFORTH_MINIMAL. L4Re support has been removed as an active target. */
#if defined(STARFORTH_MINIMAL)
typedef struct sf_mutex
{
volatile unsigned int state;
} sf_mutex_t;
#else
#include <pthread.h>
typedef struct sf_mutex
{
pthread_mutex_t handle;
} sf_mutex_t;
#endif
int sf_mutex_init(sf_mutex_t *mutex);
void sf_mutex_destroy(sf_mutex_t *mutex);
void sf_mutex_lock(sf_mutex_t *mutex);
void sf_mutex_unlock(sf_mutex_t *mutex);
#endif /* STARFORTH_PLATFORM_LOCK_H */
+177
View File
@@ -0,0 +1,177 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STARFORTH_PLATFORM_TIME_H
#define STARFORTH_PLATFORM_TIME_H
/*
* StarForth Platform Time Abstraction
*
* Provides portable timing interface for POSIX builds. (HISTORICAL: also
* supported L4Re/StarshipOS through mid-2026; removed as an active target.)
* Uses vtable pattern similar to blkio subsystem.
*
* License: See LICENSE file
*/
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Time representation (nanoseconds since epoch) */
typedef uint64_t sf_time_ns_t;
/* Timestamp string buffer size */
#define SF_TIME_STAMP_SIZE 32
/* Platform time backend vtable */
typedef struct {
/**
* @brief Get monotonic time (for performance measurement)
* @return Nanoseconds since system boot (never decreases)
*/
sf_time_ns_t (*get_monotonic_ns)(void);
/**
* @brief Get wall-clock time
* @return Nanoseconds since Unix epoch (1970-01-01 00:00:00 UTC)
* Returns 0 if RTC unavailable
*/
sf_time_ns_t (*get_realtime_ns)(void);
/**
* @brief Set wall-clock time (may require privileges)
* @param ns_since_epoch Nanoseconds since Unix epoch
* @return 0 on success, -1 on error
*/
int (*set_realtime_ns)(sf_time_ns_t ns_since_epoch);
/**
* @brief Format timestamp as human-readable string
* @param ns_since_epoch Nanoseconds since Unix epoch
* @param buf Output buffer (SF_TIME_STAMP_SIZE bytes)
* @param format_24h Use 24-hour format (1) or 12-hour (0)
* @return 0 on success, -1 on error
*/
int (*format_timestamp)(sf_time_ns_t ns_since_epoch, char *buf, int format_24h);
/**
* @brief Check if real-time clock is available
* @return 1 if RTC available, 0 if not
*/
int (*has_rtc)(void);
} sf_time_backend_t;
/* Global backend pointer (set at initialization) */
extern const sf_time_backend_t *sf_time_backend;
/* Platform-specific backend registration */
extern const sf_time_backend_t sf_time_backend_posix; /* POSIX implementation */
extern const sf_time_backend_t sf_time_backend_l4re; /* HISTORICAL: L4Re/StarshipOS implementation, no longer wired into any build (see src/platform/l4re/time.c) */
/* Convenience wrappers (inline for zero overhead).
* Define PLATFORM_TIME_NO_INLINE before including this header to suppress
* these inline definitions (e.g. when providing concrete implementations).
* When suppressed, non-inline prototypes are declared so callers can link
* to a concrete implementation (e.g. shim.c in the kernel). */
#ifndef PLATFORM_TIME_NO_INLINE
static inline sf_time_ns_t sf_monotonic_ns(void) {
return sf_time_backend->get_monotonic_ns();
}
static inline sf_time_ns_t sf_realtime_ns(void) {
return sf_time_backend->get_realtime_ns();
}
static inline int sf_set_realtime_ns(sf_time_ns_t ns) {
return sf_time_backend->set_realtime_ns(ns);
}
static inline int sf_format_timestamp(sf_time_ns_t ns, char *buf, int format_24h) {
return sf_time_backend->format_timestamp(ns, buf, format_24h);
}
static inline int sf_has_rtc(void) {
return sf_time_backend->has_rtc();
}
#else /* PLATFORM_TIME_NO_INLINE */
/* Non-inline prototypes — provided by the platform's concrete implementation. */
sf_time_ns_t sf_monotonic_ns(void);
sf_time_ns_t sf_realtime_ns(void);
int sf_set_realtime_ns(sf_time_ns_t ns);
int sf_format_timestamp(sf_time_ns_t ns, char *buf, int format_24h);
int sf_has_rtc(void);
#endif /* PLATFORM_TIME_NO_INLINE */
/* Time conversion helpers */
static inline sf_time_ns_t sf_seconds_to_ns(uint64_t seconds) {
return seconds * 1000000000ULL;
}
static inline uint64_t sf_ns_to_seconds(sf_time_ns_t ns) {
return ns / 1000000000ULL;
}
static inline uint64_t sf_ns_to_ms(sf_time_ns_t ns) {
return ns / 1000000ULL;
}
static inline uint64_t sf_ns_to_us(sf_time_ns_t ns) {
return ns / 1000ULL;
}
/* Initialize platform time backend (call once at startup) */
void sf_time_init(void);
#ifdef __cplusplus
}
#endif
#endif /* STARFORTH_PLATFORM_TIME_H */
+265
View File
@@ -0,0 +1,265 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STARFORTH_PROFILER_H
#define STARFORTH_PROFILER_H
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
/* Forward declarations */
typedef struct VM VM;
typedef struct DictEntry DictEntry;
/**
* @brief Profiling detail levels
*
* Controls the amount of profiling information collected during execution.
* Higher levels include all features from lower levels.
*/
typedef enum {
PROFILE_DISABLED = 0, /**< Profiling disabled (zero overhead) */
PROFILE_BASIC = 1, /**< Word execution frequency tracking (minimal overhead) */
PROFILE_DETAILED = 2, /**< Basic + word execution timing (5-10% overhead) */
PROFILE_VERBOSE = 3, /**< Detailed + stack/memory access patterns (15-20% overhead) */
PROFILE_FULL = 4 /**< Reserved for future use (full instrumentation) */
} ProfileLevel;
/**
* @brief Profiling measurement categories
*
* Different aspects of VM operation that can be profiled
*/
typedef enum {
PROF_VM_INIT = 0, /**< VM initialization */
PROF_VM_EXECUTE, /**< VM execution loop */
PROF_VM_COMPILE, /**< Word compilation */
PROF_DICT_LOOKUP, /**< Dictionary searches */
PROF_DICT_ADD, /**< Dictionary additions */
PROF_STACK_OPS, /**< Stack operations */
PROF_MEMORY_ACCESS, /**< Memory access operations */
PROF_WORD_EXEC, /**< Word execution */
PROF_IO_OPS, /**< I/O operations */
PROF_CONTROL_FLOW, /**< Control flow operations */
PROF_CATEGORY_COUNT /**< Total number of categories */
} ProfileCategory;
/**
* @brief Timer for measuring execution duration
*/
typedef struct {
uint64_t start_time; /**< Start timestamp */
uint64_t total_time; /**< Accumulated execution time */
uint64_t call_count; /**< Number of measurements */
uint64_t min_time; /**< Minimum recorded time */
uint64_t max_time; /**< Maximum recorded time */
const char *name; /**< Timer identifier */
} ProfileTimer;
/**
* @brief Execution statistics for a single word
*/
typedef struct {
const char *word_name; /**< Name of the profiled word */
uint64_t total_time; /**< Total execution time */
uint64_t call_count; /**< Number of executions */
uint64_t avg_time; /**< Average execution time */
uint64_t min_time; /**< Minimum execution time */
uint64_t max_time; /**< Maximum execution time */
double percentage; /**< Percentage of total runtime */
} WordProfile;
/* Memory access pattern tracking */
typedef struct {
uint64_t reads;
uint64_t writes;
uint64_t cache_hits;
uint64_t cache_misses;
uint64_t total_bytes_read;
uint64_t total_bytes_written;
} MemoryProfile;
/* Main profiler state */
typedef struct {
ProfileLevel level;
uint64_t profiling_overhead;
uint64_t total_execution_time;
/* Category timers */
ProfileTimer category_timers[PROF_CATEGORY_COUNT];
/* Word execution tracking */
WordProfile *word_profiles;
size_t word_profile_count;
size_t word_profile_capacity;
/* Memory access tracking */
MemoryProfile memory_stats;
/* Hot path detection */
uint64_t instruction_count;
uint64_t branch_count;
uint64_t loop_iterations;
/* Performance counters */
struct {
uint64_t vm_cycles;
uint64_t dict_lookups;
uint64_t stack_operations;
uint64_t memory_allocations;
uint64_t compile_operations;
} counters;
} Profiler;
/* Global profiler instance */
extern void *g_profiler;
/* Profiler lifecycle */
/**
* @brief Initialize the profiling system
* @param level Initial profiling detail level
* @return 0 on success, non-zero on failure
*/
int profiler_init(ProfileLevel level);
/**
* @brief Shutdown and cleanup the profiling system
*/
void profiler_shutdown(void);
/**
* @brief Reset all profiling statistics
*/
void profiler_reset(void);
/**
* @brief Change the current profiling detail level
* @param level New profiling level to set
*/
void profiler_set_level(ProfileLevel level);
/* Timing functions */
uint64_t profiler_get_time_ns(void);
void profiler_start_timer(ProfileCategory category);
void profiler_end_timer(ProfileCategory category);
/* Word profiling */
/**
* @brief Start timing a word execution (PROFILE_DETAILED+)
* @param entry Dictionary entry of the word being executed
*/
void profiler_word_enter(const DictEntry *entry);
/**
* @brief End timing a word execution (PROFILE_DETAILED+)
* @param entry Dictionary entry of the word being executed
*/
void profiler_word_exit(const DictEntry *entry);
/**
* @brief Track word execution frequency without timing (PROFILE_BASIC+)
* @param entry Dictionary entry of the word being executed
*
* This is a lightweight alternative to profiler_word_enter/exit that only
* increments call counters without timing overhead. Ideal for identifying
* hot words (frequently executed) for optimization.
*/
void profiler_word_count(const DictEntry *entry);
/* Memory profiling */
void profiler_memory_read(size_t bytes);
void profiler_memory_write(size_t bytes);
void profiler_memory_alloc(size_t bytes);
/* Counter increments */
void profiler_inc_vm_cycles(uint64_t cycles);
void profiler_inc_dict_lookup(void);
void profiler_inc_stack_op(void);
void profiler_inc_branch(void);
void profiler_inc_loop_iter(void);
/* Analysis and reporting */
void profiler_generate_report(void);
void profiler_print_summary(void);
void profiler_print_word_analysis(void);
void profiler_print_memory_analysis(void);
void profiler_print_hotspots(void);
/* Performance optimization suggestions */
void profiler_analyze_performance(VM *vm);
void profiler_suggest_optimizations(void);
/* Profiler macros for easy integration */
#define PROFILE_ENABLED() (0)
#define PROFILE_START(category) ((void)0)
#define PROFILE_END(category) ((void)0)
#define PROFILE_WORD_ENTER(name) ((void)0)
#define PROFILE_WORD_EXIT(name) ((void)0)
#define PROFILE_MEMORY_READ(bytes) ((void)0)
#define PROFILE_MEMORY_WRITE(bytes) ((void)0)
#define PROFILE_INC_CYCLES(n) ((void)0)
#define PROFILE_INC_DICT_LOOKUP() ((void)0)
#define PROFILE_INC_STACK_OP() ((void)0)
/* Scoped profiling helper */
typedef struct {
ProfileCategory category;
const char *word_name;
} ProfileScope;
#endif /* STARFORTH_PROFILER_H */
+305
View File
File diff suppressed because it is too large Load Diff
+55
View File
@@ -0,0 +1,55 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef REPL_H
#define REPL_H
#include "vm.h"
/*
* @brief Starts the REPL (Read-Eval-Print Loop) for the Forth virtual machine
* @param vm Pointer to the VM instance to run the REPL on
* @param script_mode If 1, suppress prompts and "ok" output (for piped input)
*/
void vm_repl(VM *vm, int script_mode);
#endif /* REPL_H */
+205
View File
@@ -0,0 +1,205 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
*** StarForth ***
rolling_window_knobs.h - Tunable Adaptive Shrinking Control
Knobs that control how the rolling window automatically learns and adapts
its size during execution. These are NOT the initial window size - they
control the self-tuning behavior.
All knobs are tunable via Makefile:
make ADAPTIVE_SHRINK_RATE=30 (shrink by 30% instead of default)
make ADAPTIVE_MIN_WINDOW_SIZE=512 (never shrink below 512)
etc.
*/
#ifndef ROLLING_WINDOW_KNOBS_H
#define ROLLING_WINDOW_KNOBS_H
#include "starforth_config.h"
/* ============================================================================
* Knob #8: ADAPTIVE_SHRINK_RATE - How aggressively to shrink the window
* ============================================================================
*
* When pattern diversity plateaus, the window shrinks by this percentage.
*
* Value: 0-99 (percentage to retain, not discard)
* ADAPTIVE_SHRINK_RATE=75 → shrink to 75% of current size (discard 25%)
* ADAPTIVE_SHRINK_RATE=50 → shrink to 50% of current size (discard 50%)
* ADAPTIVE_SHRINK_RATE=90 → shrink to 90% of current size (discard 10%)
*
* Rationale:
* Higher (90+): Conservative, slow learning, larger final window
* Default (75): Balanced - learns in 3-4 shrink cycles
* Lower (50): Aggressive, fast learning, minimal final window
*
* Trade-off:
* Higher = safer (more pattern capture margin, slower adaptation)
* Lower = leaner (less memory overhead, faster optimization)
*
* Default: see starforth_config.h (STARFORTH_CONFIG_ADAPTIVE_SHRINK_RATE_DEFAULT)
* Range: 50-95 (below 50 is too aggressive, above 95 barely shrinks)
*
* Tuning: make ADAPTIVE_SHRINK_RATE=80
*/
/* ============================================================================
* Knob #9: ADAPTIVE_MIN_WINDOW_SIZE - Minimum window size (safety floor)
* ============================================================================
*
* The window will never shrink below this size, even if diversity plateaus.
* Prevents over-optimization that might miss emerging patterns.
*
* Value: 64-2048 (in word IDs, not bytes)
* ADAPTIVE_MIN_WINDOW_SIZE=256 → don't shrink below 256
* ADAPTIVE_MIN_WINDOW_SIZE=128 → don't shrink below 128
* ADAPTIVE_MIN_WINDOW_SIZE=512 → don't shrink below 512
*
* Rationale:
* Smaller (128): Lean optimization, accept lower pattern capture
* Default (256): Balanced - typical workload needs 200-250 patterns
* Larger (512): Conservative, handles complex workloads
*
* Trade-off:
* Smaller = less memory, risk of missing edge-case patterns
* Larger = more memory, safer for unpredictable workloads
*
* Default: see starforth_config.h (STARFORTH_CONFIG_ADAPTIVE_MIN_WINDOW_SIZE_DEFAULT)
* Range: 64-1024
*
* Tuning: make ADAPTIVE_MIN_WINDOW_SIZE=512
*/
/* ============================================================================
* Knob #10: ADAPTIVE_CHECK_FREQUENCY - How often to check diversity
* ============================================================================
*
* The system checks pattern diversity every N executions.
* More frequent checks = faster response to saturation, more overhead.
*
* Value: 32-1024 (execution count between checks)
* ADAPTIVE_CHECK_FREQUENCY=128 → check after every 128 executions
* ADAPTIVE_CHECK_FREQUENCY=256 → check after every 256 executions
* ADAPTIVE_CHECK_FREQUENCY=512 → check after every 512 executions
*
* Rationale:
* More frequent (128): Responsive learning, detects saturation quickly
* Default (256): Balanced - good responsiveness, minimal overhead
* Less frequent (512): Lazy learning, smaller monitoring overhead
*
* Trade-off:
* More = faster adaptation, slightly more computation
* Less = slower adaptation, minimal overhead
*
* Default: see starforth_config.h (STARFORTH_CONFIG_ADAPTIVE_CHECK_FREQUENCY_DEFAULT)
* Range: 32-1024
*
* Tuning: make ADAPTIVE_CHECK_FREQUENCY=128
*/
/* ============================================================================
* Knob #11: ADAPTIVE_GROWTH_THRESHOLD - Pattern growth rate that signals saturation
* ============================================================================
*
* When pattern diversity growth drops below this rate, window can shrink.
* Expressed as percentage (0-100).
*
* Value: 0-10 (as percentage, 0=0%, 10=10%)
* ADAPTIVE_GROWTH_THRESHOLD=1 → shrink when growth < 1% (aggressive)
* ADAPTIVE_GROWTH_THRESHOLD=2 → shrink when growth < 2% (default, balanced)
* ADAPTIVE_GROWTH_THRESHOLD=5 → shrink when growth < 5% (conservative)
*
* Rationale:
* Lower (0.5%): Very aggressive, assumes patterns found early
* Default (1%): Balanced - empirically tested, works well
* Higher (5%): Conservative, waits for stronger saturation signal
*
* Trade-off:
* Lower = eager shrinking, risk of missing late-arriving patterns
* Higher = cautious shrinking, longer time to final window size
*
* Default: see starforth_config.h (STARFORTH_CONFIG_ADAPTIVE_GROWTH_THRESHOLD_DEFAULT)
* Range: 0-10
*
* Note: Internally, this is applied as: growth_rate < (threshold / 100.0)
* E.g., ADAPTIVE_GROWTH_THRESHOLD=1 means growth_rate < 0.01
*
* Tuning: make ADAPTIVE_GROWTH_THRESHOLD=2
*/
/* ============================================================================
* Summary Table: How Knobs Interact
* ============================================================================
*
* Scenario 1: "Fast Learning, Lean Final Size"
* ADAPTIVE_SHRINK_RATE=50
* ADAPTIVE_MIN_WINDOW_SIZE=128
* ADAPTIVE_CHECK_FREQUENCY=128
* ADAPTIVE_GROWTH_THRESHOLD=0
* → Shrinks aggressively, frequently, to minimal size
* → Best for: Memory-constrained systems, simple workloads
*
* Scenario 2: "Balanced (Default)" -- see starforth_config.h for the exact
* shipped default of each knob; illustrative values below.
* ADAPTIVE_SHRINK_RATE=50
* ADAPTIVE_MIN_WINDOW_SIZE=256
* ADAPTIVE_CHECK_FREQUENCY=512
* ADAPTIVE_GROWTH_THRESHOLD=5
* → Good balance, typical FORTH programs
* → Best for: General-purpose systems
*
* Scenario 3: "Conservative, Safe"
* ADAPTIVE_SHRINK_RATE=90
* ADAPTIVE_MIN_WINDOW_SIZE=512
* ADAPTIVE_CHECK_FREQUENCY=512
* ADAPTIVE_GROWTH_THRESHOLD=5
* → Slow, cautious shrinking, large safety margin
* → Best for: Complex workloads, unpredictable patterns
*
*/
#endif /* ROLLING_WINDOW_KNOBS_H */
+265
View File
@@ -0,0 +1,265 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
*** StarForth ***
rolling_window_of_truth.h - Execution history for deterministic metrics seeding
The "Rolling Window of Truth" captures actual execution sequences to:
1. Seed initial metrics after POST (hot-words cache, pipelining context)
2. Provide deterministic record of all word executions
3. Enable reproducible, provable optimization decisions
4. Form foundation for formal verification (Isabelle/HOL)
Vision: Every decision is observable, traceable, and mathematically provable.
*/
#ifndef ROLLING_WINDOW_OF_TRUTH_H
#define ROLLING_WINDOW_OF_TRUTH_H
#include <stdint.h>
#include "vm.h"
/* ============================================================================
* Rolling Window of Truth
* ============================================================================
*
* Circular buffer of word IDs representing recent execution sequence.
* Used to:
* 1. Seed metrics after POST completes
* 2. Provide execution context for pipelining decisions
* 3. Enable reproducibility and formal verification
*
* NOTE: Structure is defined in vm.h to avoid circular includes.
* See vm.h for structure definition and ROLLING_WINDOW_SIZE constant.
*/
/* ============================================================================
* Rolling Window API
* ============================================================================
*/
/*
* Initialize rolling window of truth.
* Called during VM initialization.
*
* @param window Pointer to uninitialized RollingWindowOfTruth
* @return 0 on success, -1 on malloc failure
*/
int rolling_window_init(RollingWindowOfTruth * window);
/*
* Record a word execution in the rolling window.
* Called after each word executes (in inner interpreter).
*
* THREAD SAFETY: This function is NOT thread-safe. Caller MUST hold
* vm->tuning_lock when calling from multiple threads (main VM + heartbeat).
*
* Called from:
* - Main VM thread (inner interpreter loop, src/vm.c:1162)
* - Heartbeat worker thread (through rolling_window_service, src/vm.c:743)
*
* MUST ALWAYS be protected by:
* sf_mutex_lock(&vm->tuning_lock);
* rolling_window_record_execution(&vm->rolling_window, word_id);
* sf_mutex_unlock(&vm->tuning_lock);
*
* Extremely lightweight (constant time):
* - Write to circular buffer
* - Increment counters
* - 2-3 CPU cycles (plus lock overhead ~100 cycles uncontended)
*
* @param window Rolling window to update
* @param word_id Word that just executed
* @return 0 on success, -1 on error
*/
int rolling_window_record_execution(RollingWindowOfTruth* window, uint32_t word_id);
/*
* Get recent execution sequence for context.
* Returns pointer to last N words (or fewer if not enough executions yet).
*
* @param window Rolling window
* @param depth How many previous words to return (1 to ROLLING_WINDOW_SIZE)
* @param out_sequence Output array (caller allocates, must be >= depth)
* @return Number of words written to out_sequence (may be < depth if cold start)
*/
uint32_t rolling_window_get_recent_sequence(const RollingWindowOfTruth* window,
uint32_t depth,
uint32_t* out_sequence);
/*
* Get most frequent word in rolling window.
* Useful for identifying hot words immediately after POST.
*
* @param window Rolling window
* @param dict_size Total number of words in dictionary (for bounds check)
* @return Word ID of most frequent execution, or 0 if window not warm
*/
uint32_t rolling_window_find_hottest_word(const RollingWindowOfTruth* window,
uint32_t dict_size);
/*
* Get transition frequency: how often word_b follows word_a in window.
*
* Useful for seeding pipelining context predictions.
*
* @param window Rolling window
* @param word_a First word in sequence
* @param word_b Second word in sequence
* @return Count of (word_a → word_b) transitions in window
*/
uint64_t rolling_window_count_transition(const RollingWindowOfTruth* window,
uint32_t word_a,
uint32_t word_b);
/*
* Check if window is warm (contains representative data).
* Seeding functions should check this before using window data.
*
* @param window Rolling window
* @return 1 if window is warm (>= ROLLING_WINDOW_SIZE executions), 0 otherwise
*/
int rolling_window_is_warm(const RollingWindowOfTruth* window);
/*
* Get detailed statistics string for diagnostics.
*
* @param window Rolling window
* @return Formatted string (caller must free)
*/
char* rolling_window_stats_string(const RollingWindowOfTruth* window);
/*
* Reset rolling window (clear all data).
*
* @param window Rolling window to reset
*/
void rolling_window_reset(RollingWindowOfTruth * window);
/*
* Free all memory allocated for rolling window.
* Called during VM cleanup.
*
* @param window Rolling window to clean up
*/
void rolling_window_cleanup(RollingWindowOfTruth * window);
/* ============================================================================
* Bootstrap Data Analysis API
* ============================================================================
*
* Used to analyze rolling window data and determine statistically significant
* window sizes for cold-start systems (un-physics VM).
*/
/*
* Export full execution history for external analysis.
* Used by bootstrap analyzer to determine optimal window size.
*
* Returns the complete circular buffer linearized in chronological order.
* Caller allocates output buffer; function fills it with execution sequence.
*
* @param window Rolling window to export
* @param out_sequence Output buffer (caller allocates, must be >= total_executions)
* @param max_count Maximum entries to write
* @return Number of word IDs written to out_sequence
*/
uint64_t rolling_window_export_execution_history(const RollingWindowOfTruth* window,
uint32_t* out_sequence,
uint64_t max_count);
/*
* Analyze pattern capture rate for a given window size.
* Measures what percentage of unique transitions are captured.
*
* Algorithm:
* 1. Scan execution history with sliding window of given size
* 2. Count unique (context, next_word) patterns observed
* 3. Return: (patterns_captured / total_unique_patterns) * 100
*
* Used for offline analysis to determine reasonable starting window size.
*
* @param window Rolling window with execution data
* @param test_window_size Window size to test (e.g., 256, 512, 1024)
* @return Pattern capture rate (0-100%)
*/
double rolling_window_pattern_capture_rate(const RollingWindowOfTruth* window,
uint32_t test_window_size);
/* ============================================================================
* Adaptive Window Sizing API
* ============================================================================
*
* Automatic continuous self-tuning of window size during execution.
* Called automatically during normal operation - no user intervention needed.
*/
/*
* Measure pattern diversity in rolling window.
* Counts unique adjacent transitions (word_a → word_b) to indicate workload variability.
*
* Used by dictionary heat optimization to decide lookup strategy:
* - High diversity (>70) = use heat-aware lookup (patterns are varied)
* - Low diversity (<30) = use naive lookup (patterns are stable)
*
* @param window Rolling window to analyze
* @return Count of unique transitions in window
*/
uint64_t rolling_window_measure_diversity(const RollingWindowOfTruth* window);
/*
* Check and apply adaptive window shrinking.
* Called periodically by rolling_window_record_execution.
* Measures pattern diversity and shrinks window if diminishing returns detected.
*
* This function is called automatically - users never invoke it directly.
* It runs every 256 executions after window becomes warm.
*
* @param window Rolling window (modified in-place if shrinking occurs)
*/
void rolling_window_check_adaptive_shrink(RollingWindowOfTruth* window);
void rolling_window_service(RollingWindowOfTruth* window);
#endif /* ROLLING_WINDOW_OF_TRUTH_H */

Some files were not shown because too many files have changed in this diff Show More