Stage D: parked-idle VMs are killable, KILL unregisters; fix uninitialized pending_reap (FABRIC-3.8 §3.5, G6)
sk_vm_parked_idle(): saved context + exactly its own IDLE frame. capsule_vm_kill_refusal() is the single kill rule, shared by capsule_vm_kill() and the KILL word: refuse SWITCHED_OUT mid-task, parked with mail pending, or the VM running; allow parked-idle. capsule_vm_kill() now unregisters the switch slot (G6). Finding fixed: vm_registry_alloc() never initialized pending_reap (kmalloc does not zero); C-b's reap_pending walks every participant, so garbage reaped a healthy VM (seen live before any KILL). Now zeroed at alloc. Probe (reverted): baseline KILL refused, slots 3->4->4 (FAIL, proves G6); with Stage D dprobe parked idle, KILL dead, slots 3->4->3, PASS on amd64/ aarch64/riscv64. Acceptance: dict_hash unchanged, relay 3, idle growth 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
06bcab504d
commit
604ad7aadc
@@ -222,6 +222,13 @@ void sk_vm_idle_point(void) {
|
||||
}
|
||||
}
|
||||
|
||||
int sk_vm_parked_idle(const VM *vm) {
|
||||
return vm && vm->native_stack_saved_sp != 0 &&
|
||||
vm->frames.count == 1 &&
|
||||
vm->frames.entries[0].kind == VM_FRAME_IDLE &&
|
||||
vm_uuid_equal(vm->frames.entries[0].vm_id, vm->stadium_vm_id);
|
||||
}
|
||||
|
||||
int sk_vm_context_switch(VM *from, VM *to) {
|
||||
uint64_t new_sp;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user