357 lines
12 KiB
Plaintext
357 lines
12 KiB
Plaintext
// Moved from docs/src/internal/PHYSICS_IMPLEMENTATION_STATUS.adoc to docs/working/scratch/src/internal/PHYSICS_IMPLEMENTATION_STATUS.adoc on 2026-06-16 (docs reorg Phase 2)
|
|
= Physics Engine Implementation Status: POSIX vs L4Re Porting Strategy
|
|
:toc: left
|
|
:toclevels: 2
|
|
xref:../README.adoc[← Back to Documentation Index]
|
|
|
|
== Executive Summary
|
|
|
|
**Good News**: The word execution hooks are **already wired**. The `physics_metadata_touch()` calls are in place at both:
|
|
|
|
1. **Outer interpreter** (`src/vm.c:533`) - for primitive word execution
|
|
2. **Colon word executor** (`src/vm.c:456`) - for nested word calls
|
|
|
|
**Current Status**: Phase 1 infrastructure is complete, but the **POSIX/L4Re abstraction needs refinement** to follow the existing porting strategy (currently mixing `#ifdef` inline, should use vtable pattern like `platform_time.h`).
|
|
|
|
---
|
|
|
|
== What's WIRED NOW ✅
|
|
|
|
=== Execution Hook Points (Already Called)
|
|
|
|
Each word execution updates physics metadata:
|
|
|
|
[source,c]
|
|
----
|
|
// Outer interpreter (vm.c:533) - direct word execution
|
|
entry->func(vm);
|
|
physics_metadata_touch(entry, entry->entropy, sf_monotonic_ns());
|
|
|
|
// Colon word executor (vm.c:456) - nested word calls
|
|
w->func(vm);
|
|
physics_metadata_touch(w, w->entropy, sf_monotonic_ns());
|
|
----
|
|
|
|
Both paths update:
|
|
- `temperature_q8` - via exponential moving average from entropy
|
|
- `last_active_ns` - monotonic timestamp of last execution
|
|
- Already integrated with profiler hooks (`profiler_word_enter/exit`)
|
|
|
|
=== Dictionary Initialization
|
|
|
|
[source,c]
|
|
----
|
|
// dictionary_management.c - when words are created
|
|
physics_metadata_init(entry, header_bytes);
|
|
physics_metadata_apply_seed(entry); // Pre-seed hotwords
|
|
----
|
|
|
|
Seeds 20 high-impact words (IF, LOOP, EMIT, BLOCK, SAVE-BUFFERS, etc.) with domain knowledge from `src/physics_metadata.c`.
|
|
|
|
=== Analytics Heap & Host Snapshots
|
|
|
|
[source,c]
|
|
----
|
|
// main.c - startup/shutdown
|
|
physics_runtime_init(size_t bytes); // 10 MiB default
|
|
physics_runtime_shutdown();
|
|
|
|
// Called on demand (not automatic yet)
|
|
physics_host_snapshot(&snapshot); // Captures scheduler state
|
|
physics_analytics_publish_event(...); // Publishes to ring buffer
|
|
----
|
|
|
|
---
|
|
|
|
== What's INCOMPLETE ⏳
|
|
|
|
=== 1. POSIX/L4Re Abstraction Pattern
|
|
|
|
**Problem**: Architecture differs from established porting strategy.
|
|
|
|
**Current Code** (`src/physics_runtime.c`):
|
|
|
|
Inline conditionals throughout:
|
|
----
|
|
#if !defined(__l4__)
|
|
snapshot_posix(); // ~90 lines, comprehensive
|
|
#endif
|
|
|
|
#ifdef __l4__
|
|
snapshot_l4re(); // ~15 lines, STUBBED
|
|
#endif
|
|
----
|
|
|
|
**Comparison: Platform Time Pattern** (`include/platform_time.h`):
|
|
|
|
Uses vtable with separate backend implementations:
|
|
----
|
|
include/platform_time.h
|
|
├─ sf_time_backend_t vtable
|
|
├─ extern const sf_time_backend_t sf_time_backend_posix;
|
|
├─ extern const sf_time_backend_t sf_time_backend_l4re;
|
|
└─ sf_time_init() [selects backend at runtime]
|
|
|
|
src/platform/linux/time.c [POSIX implementation]
|
|
src/platform/l4re/time.c [L4Re implementation]
|
|
----
|
|
|
|
**Verdict**: Physics runtime should follow same pattern for:
|
|
- Clear separation of platform concerns
|
|
- Parallel development (platform teams work independently)
|
|
- Testability (POSIX fully testable without L4Re headers)
|
|
- Governance alignment (matches existing architecture)
|
|
|
|
=== 2. Periodic Host Snapshot Capture
|
|
|
|
Currently `physics_host_snapshot()` is **defined but never called automatically**.
|
|
|
|
Missing:
|
|
- No heartbeat mechanism to invoke snapshots
|
|
- No events published to analytics ring buffer
|
|
- Analytics heap is allocated but unused
|
|
|
|
=== 3. Temperature Decay Model
|
|
|
|
Currently `temperature_q8` is updated on execution but **never decayed**.
|
|
|
|
Missing:
|
|
- Exponential moving average with configurable half-life
|
|
- Cooling logic for inactive words
|
|
- No age-based eviction strategy
|
|
|
|
---
|
|
|
|
== POSIX Side Completeness ✅
|
|
|
|
=== What Works Today
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
|Signal |Implementation
|
|
|CPU count |`sysconf(_SC_NPROCESSORS_ONLN)` ✅
|
|
|Scheduler policy |`sched_getscheduler(0)` ✅
|
|
|Scheduler priority |`sched_getparam()` ✅
|
|
|Time quantum |`sched_rr_get_interval()` ✅
|
|
|Load average |`getloadavg()` (GNU extension) ✅
|
|
|PSI metrics |`/proc/pressure/{cpu,io,memory}` ✅
|
|
|/proc/stat jiffies |CPU total & idle counters ✅
|
|
|cgroup v2 |`cpu.stat` and `memory.current` ✅
|
|
|Flag bits |Advertise which sources populated ✅
|
|
|===
|
|
|
|
=== Graceful Degradation
|
|
|
|
The POSIX implementation is **well-defended**:
|
|
|
|
- `getloadavg()` - guarded by `_GNU_SOURCE`
|
|
- PSI files - `read_psi_file()` returns 0 if unavailable (kernel <4.20)
|
|
- cgroup v2 - `resolve_cgroup_path()` returns -1 gracefully
|
|
- All missing metrics result in `flags = 0` for that category
|
|
|
|
**Verdict**: POSIX path is **production-ready** and **robust against missing procfs interfaces**.
|
|
|
|
---
|
|
|
|
== L4Re Side Status ⏳
|
|
|
|
=== Current Implementation (Stub)
|
|
|
|
From `src/physics_runtime.c:487-500`:
|
|
|
|
[source,c]
|
|
----
|
|
#ifdef __l4__
|
|
static int snapshot_l4re(physics_host_snapshot_t *out) {
|
|
memset(out, 0, sizeof(*out));
|
|
out->backend = PHYSICS_HOST_BACKEND_L4RE;
|
|
out->monotonic_time_ns = sf_monotonic_ns(); // ✅ works (via platform_time)
|
|
out->realtime_ns = sf_realtime_ns(); // ✅ works (via platform_time)
|
|
|
|
l4_kernel_info_t *kip = l4re_kip();
|
|
(void) kip;
|
|
out->cpu_count = 1u; // ❌ TODO: query processor count from KIP
|
|
|
|
out->backend_seq = ++g_runtime.backend_seq;
|
|
return 0;
|
|
}
|
|
#endif
|
|
----
|
|
|
|
=== What Could Be Added
|
|
|
|
**KIP Queries** (via `l4re_kip()`):
|
|
[source,c]
|
|
----
|
|
l4_kernel_info_t *kip = l4re_kip();
|
|
out->cpu_count = l4_kip_nr_cpus(kip); // once API exposed
|
|
----
|
|
|
|
**Scheduler Info** (via `l4_scheduler_info()`):
|
|
[source,c]
|
|
----
|
|
l4_sched_param_t params;
|
|
l4_scheduler_info(L4_MYSELF, ¶ms);
|
|
out->scheduler_quantum_ns = params.quantum;
|
|
out->scheduler_priority = params.prio;
|
|
----
|
|
|
|
**RTC Synchronization**: Already integrated in `src/platform/l4re/time.c` ✅
|
|
|
|
**IO Server Capabilities** (vbus_storage, ahci_chan): Future phases
|
|
|
|
---
|
|
|
|
== Recommended Refactoring: Vtable Pattern
|
|
|
|
To align with the **existing porting strategy**, refactor physics snapshot to use the vtable pattern:
|
|
|
|
=== New File Structure
|
|
|
|
[source]
|
|
----
|
|
include/physics_runtime.h [unchanged - public API]
|
|
|
|
src/physics_runtime.c [refactored]
|
|
├─ physics_analytics_header_t [unchanged]
|
|
├─ physics_runtime_state_t [unchanged]
|
|
├─ analytics_heap_allocate() [unchanged]
|
|
├─ physics_analytics_publish_event() [unchanged]
|
|
├─ typedef physics_snapshot_backend_t [NEW vtable]
|
|
├─ extern const physics_snapshot_backend_t physics_snapshot_backend_posix
|
|
├─ extern const physics_snapshot_backend_t physics_snapshot_backend_l4re
|
|
└─ physics_host_snapshot() [NEW dispatcher]
|
|
|
|
src/platform/linux/snapshot.c [NEW - POSIX backend]
|
|
├─ parse_avg_milli()
|
|
├─ read_psi_file()
|
|
├─ read_proc_stat_totals()
|
|
├─ resolve_cgroup_path()
|
|
├─ read_cgroup_cpu_usage_us()
|
|
├─ read_cgroup_memory_current()
|
|
└─ snapshot_posix_impl()
|
|
|
|
src/platform/l4re/snapshot.c [NEW - L4Re backend]
|
|
├─ snapshot_l4re_impl()
|
|
└─ [Future: KIP, scheduler queries]
|
|
----
|
|
|
|
=== Benefits
|
|
|
|
1. **Separation of Concerns**: POSIX code doesn't pollute L4Re builds (and vice versa)
|
|
2. **Parallel Development**: Platform teams can work independently
|
|
3. **Testability**: POSIX path fully testable without L4Re headers/libraries
|
|
4. **Consistency**: Matches `platform_time.h` pattern already in codebase
|
|
5. **Extensibility**: Easy to add new backends (embedded, minimal, test harnesses)
|
|
6. **Documentation**: Clear boundaries make porting requirements explicit
|
|
|
|
---
|
|
|
|
== Answers to Your Questions
|
|
|
|
=== Q1: Is the POSIX side fully wired such as emulation of KIP?
|
|
|
|
✅ POSIX side is **feature-complete** for what POSIX can measure::
|
|
- Uses appropriate POSIX APIs for everything (no fake/emulated KIP)
|
|
- Gracefully handles missing procfs files (PSI, cgroup v2)
|
|
- Well-integrated with scheduler and profiler
|
|
|
|
❌ There is **NO KIP emulation** (intentional and correct)::
|
|
- No point creating fake KIP on POSIX
|
|
- Each backend should use native APIs of its platform
|
|
|
|
🔴 Missing: **Periodic heartbeat** to actually call the snapshot function::
|
|
- Function is defined but never invoked
|
|
- Need mechanism to capture host state periodically
|
|
- Events should be published to analytics ring buffer
|
|
|
|
=== Q2: Clear division with overall porting strategy?
|
|
|
|
🟡 **Currently**: Inline `#ifdef` throughout physics_runtime.c::
|
|
- **Not** following platform_time pattern
|
|
- Mixes platform-specific logic in same file
|
|
- Makes L4Re development harder (can't test without L4Re headers)
|
|
|
|
✅ **Recommended**: Refactor to vtable + separate backend implementations::
|
|
- Follows platform_time.h pattern (already proven architecture)
|
|
- Aligns with porting strategy (clear platform abstraction)
|
|
- Enables independent platform development
|
|
|
|
=== Q3: What should we tackle for Option A (Wire Execution Counting)?
|
|
|
|
✅ Execution hooks are **already wired** - no action needed::
|
|
- Both outer interpreter and colon executor paths call `physics_metadata_touch()`
|
|
- Temperature updates are calculated correctly
|
|
- No changes needed to execution path
|
|
|
|
🟡 Need to add: **Periodic host snapshot capture**::
|
|
- Call `physics_host_snapshot()` on VM heartbeat
|
|
- Publish events to analytics ring buffer
|
|
- Can be added to REPL input loop or VM tick
|
|
|
|
🟡 Need to add: **Temperature decay model**::
|
|
- Exponential moving average with configurable half-life
|
|
- Implement in `physics_metadata.c` alongside seed table
|
|
- Test decay across multiple execution cycles
|
|
|
|
💡 **Recommendation**: Start POSIX-first, then mirror to L4Re::
|
|
1. Verify temperature updates in tests (starforth_words_test.c)
|
|
2. Add periodic snapshot capture
|
|
3. Implement decay model
|
|
4. Refactor to vtable pattern once logic is proven
|
|
|
|
---
|
|
|
|
== Summary: Execution Status by Component
|
|
|
|
[cols="1,1,1,3",options="header"]
|
|
|===
|
|
|Component |POSIX |L4Re |Status
|
|
|Host snapshot |Comprehensive |Stub (1 CPU) |🟡 Needs platform abstraction
|
|
|PSI metrics |Full (4.20+) |N/A |🟢 POSIX complete
|
|
|Scheduler info |Via sched APIs |Via KIP |🟡 L4Re TODO
|
|
|Execution hooks |Wired ✅ |Wired ✅ |🟢 COMPLETE
|
|
|Metadata init |Wired ✅ |Wired ✅ |🟢 COMPLETE
|
|
|Periodic capture |Not called |Not called |🔴 MISSING
|
|
|Temperature decay |Calculated |Calculated |🟡 No decay logic
|
|
|Profiler integration |Not wired |Not wired |🔴 MISSING
|
|
|Analytics heap |Ready |Ready |🟢 COMPLETE
|
|
|===
|
|
|
|
---
|
|
|
|
== Immediate Action Items
|
|
|
|
For **Option A (Wire Execution Counting)**:
|
|
|
|
1. **Verify Temperature Updates Work**
|
|
- Create test in `src/test_runner/modules/starforth_words_test.c`
|
|
- Define word, execute N times, inspect `temperature_q8`
|
|
- Verify EMA calculation is correct
|
|
|
|
2. **Add Periodic Host Snapshots**
|
|
- Hook `physics_host_snapshot()` into REPL input loop or VM tick
|
|
- Publish snapshots to analytics ring buffer
|
|
- Verify events appear in heap dump
|
|
|
|
3. **Implement Temperature Decay**
|
|
- Add exponential moving average with half-life
|
|
- Implement in `physics_metadata.c`
|
|
- Test decay behavior over multiple ticks
|
|
|
|
4. **Refactor to Platform Abstraction** (After proving logic works)
|
|
- Create `include/physics_snapshot_backend.h` with vtable
|
|
- Extract POSIX code to `src/platform/linux/snapshot.c`
|
|
- Create stub for `src/platform/l4re/snapshot.c`
|
|
- Update dispatcher in `src/physics_runtime.c`
|
|
|
|
---
|
|
|
|
== References
|
|
|
|
- Physics Scheduling Plan: xref:./PHYSICS_SCHEDULING_PLAN.adoc[PHYSICS_SCHEDULING_PLAN.adoc]
|
|
- Physics Signal Map: xref:./PHYSICS_SIGNAL_MAP.adoc[PHYSICS_SIGNAL_MAP.adoc]
|
|
- Platform Time Abstraction: `include/platform_time.h` (reference implementation)
|
|
- Word Execution: `src/vm.c` (lines 456, 533, 507-533)
|
|
- Physics Metadata: `src/physics_metadata.c`, `include/physics_metadata.h`
|
|
- Physics Runtime: `src/physics_runtime.c`, `include/physics_runtime.h` |