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:
@@ -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
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
Reference in New Issue
Block a user