feat(log): LOG-FLUSH -- a VM's log records reach Artemis's log ring; and the ring keeps its order when it grows
FABRIC-3 SXXXII.4's deferred LOG-FLUSH, built to the 2026-10-14 rulings (SXXXVIII): everything a VM logs, at or above the log level, goes into its own buffer; it goes to Artemis on LOG-FLUSH, when full, and at once on an ERROR, as one kernel-Hermes LOG_BATCH message she writes on her own turn, the source being the sender the kernel stamped. Records that cannot go yet are counted and reported with the next flush. LOG-SHOW (Hera only) reads the ring back -- it had no reader. Found by the first test that filled it: ring growth overwrote the oldest record and put blank slots inside the live range. Fixed test first. Three ISAs: POST 1052 passed; new parity baseline word_count=526 hash=0x82f4ae7cb2e2d424 (deliberate). CLAUDE.md: Phase 8 PKI closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5e26fad30d
commit
4da370f492
+35
-5
@@ -116,14 +116,32 @@ int log_region_append(uint8_t level, uint64_t timestamp,
|
||||
uint32_t total_slots = ctrl.devblocks * LOG_SLOTS_PER_DEVBLOCK;
|
||||
if (ctrl.record_count >= total_slots) {
|
||||
if (ctrl.devblocks < LOG_REGION_MAX_DEVBLOCKS) {
|
||||
/* Grow: new slots appear at indices [old_total_slots ..
|
||||
* new_total_slots-1], nothing already written moves -- safe
|
||||
* to do at any point in the ring's lifecycle regardless of
|
||||
* wrap state, since head/tail are slot INDICES modulo
|
||||
* total_slots, and the modulus is simply larger from here on. */
|
||||
/* Grow: new slots appear at indices [old_total .. new_total-1].
|
||||
* The ring is full here, so head == tail, and in ring order the
|
||||
* records run head..old_total-1 then 0..head-1. The new slots
|
||||
* must come after the newest record and before the oldest, so
|
||||
* the records from head on move up by the slots added, and the
|
||||
* next write goes into the gap they leave (or, with head at 0,
|
||||
* simply at old_total). Until 2026-10-14 nothing moved and
|
||||
* tail stayed put: the next write overwrote the oldest record,
|
||||
* and the blank new slots read back as records inside the live
|
||||
* range (FABRIC-3.md SXXXVIII -- first exercised by LOG-FLUSH). */
|
||||
uint32_t old_total = total_slots, added, i;
|
||||
ctrl.devblocks += LOG_REGION_GROWTH_INCREMENT;
|
||||
if (ctrl.devblocks > LOG_REGION_MAX_DEVBLOCKS) ctrl.devblocks = LOG_REGION_MAX_DEVBLOCKS;
|
||||
total_slots = ctrl.devblocks * LOG_SLOTS_PER_DEVBLOCK;
|
||||
added = total_slots - old_total;
|
||||
if (ctrl.head_slot == 0) {
|
||||
ctrl.tail_slot = old_total;
|
||||
} else {
|
||||
for (i = old_total; i-- > ctrl.head_slot; ) {
|
||||
log_slot_t moving;
|
||||
if (log_region_read_slot(i, &moving) != 0) return -1;
|
||||
if (log_region_write_slot(i + added, &moving) != 0) return -1;
|
||||
}
|
||||
ctrl.tail_slot = ctrl.head_slot;
|
||||
ctrl.head_slot += added;
|
||||
}
|
||||
}
|
||||
if (ctrl.record_count >= total_slots) {
|
||||
/* Still full (growth ceiling already reached) -- evict oldest,
|
||||
@@ -175,3 +193,15 @@ int log_region_append(uint8_t level, uint64_t timestamp,
|
||||
|
||||
return log_region_ctrl_write(&ctrl);
|
||||
}
|
||||
|
||||
int log_region_read_recent(uint32_t back, log_slot_t *out) {
|
||||
log_region_ctrl_t ctrl;
|
||||
uint32_t total_slots;
|
||||
|
||||
if (!out) return -1;
|
||||
if (log_region_ctrl_read(&ctrl) != 0) return -1;
|
||||
if (back >= ctrl.record_count) return 1;
|
||||
total_slots = ctrl.devblocks * LOG_SLOTS_PER_DEVBLOCK;
|
||||
if (total_slots == 0) return 1;
|
||||
return log_region_read_slot((ctrl.tail_slot + total_slots - 1u - back) % total_slots, out);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user