S156 · SOURCE-BOUND GATE EVIDENCE
G8i: dormant per-CPU runtime model
Operations --test hedefi → simulation public mod g8i_runtime bağı → kaynak kesiti Bu sayfa yalnız S156 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.
S156Focused kod testiOperations id exactsource SHA exacttest target exact
operation: g8i-dormant-runtime-model-partial
uygulama/model · focused test · Operations · 3 exact excerpt
sequence-bound=true · implementation-bound=false
01 · Testin bağlı olduğu uygulama/model kodu
Kapının yürüttüğü gerçek kaynak
tam Rust öğesiL1–L200
simulation/src/g8i_runtime.rs::CpuState
//! G8i dormant runtime model.
//!
//! This state machine consumes the S155 ownership model without wiring the
//! production global scheduler or exception assembly. It is the next
//! fail-closed source gate: local dequeue, current-task ownership, exception
//! entry/return and quiescent WFI are explicit per-CPU states.
use crate::g8i_runqueue::{
ExceptionFrame, PerCpuRunQueueModel, RunQueueError, TaskToken, MAX_CPUS,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CpuState {
Idle,
Running,
InException,
Wfi,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RuntimeError {
Queue(RunQueueError),
CurrentAlreadyOwned,
NoCurrentTask,
WrongCurrentTask,
WfiWhileRunning,
WfiWithRunnableTask,
InvalidStateTransition,
ExceptionWhileNotRunning,
ReturnWhileNotInException,
}
impl From<RunQueueError> for RuntimeError {
fn from(error: RunQueueError) -> Self {
Self::Queue(error)
}
}
pub struct DormantG8iRuntime {
queues: PerCpuRunQueueModel,
state: [CpuState; MAX_CPUS],
current: [Option<TaskToken>; MAX_CPUS],
}
impl DormantG8iRuntime {
pub const fn new() -> Self {
Self {
queues: PerCpuRunQueueModel::new(),
state: [CpuState::Idle; MAX_CPUS],
current: [None; MAX_CPUS],
}
}
fn valid_cpu(cpu: usize) -> Result<(), RuntimeError> {
if cpu < MAX_CPUS {
Ok(())
} else {
Err(RuntimeError::Queue(RunQueueError::InvalidCpu))
}
}
fn current_task_present(&self, task_id: u64) -> bool {
self.current.iter().flatten().any(|task| task.id == task_id)
}
pub fn publish_local(&mut self, cpu: usize, task: TaskToken) -> Result<(), RuntimeError> {
Self::valid_cpu(cpu)?;
if self.current_task_present(task.id) {
return Err(RuntimeError::Queue(RunQueueError::DuplicateTask));
}
self.queues.enqueue_local(cpu, task)?;
if self.state[cpu] == CpuState::Wfi {
self.state[cpu] = CpuState::Idle;
}
Ok(())
}
pub fn publish_remote(
&mut self,
source_cpu: usize,
target_cpu: usize,
task: TaskToken,
generation: u64,
) -> Result<(), RuntimeError> {
Self::valid_cpu(source_cpu)?;
Self::valid_cpu(target_cpu)?;
if self.current_task_present(task.id) {
return Err(RuntimeError::Queue(RunQueueError::DuplicateTask));
}
self.queues
.request_remote_enqueue(source_cpu, target_cpu, task, generation)?;
if self.state[target_cpu] == CpuState::Wfi {
self.state[target_cpu] = CpuState::Idle;
}
Ok(())
}
pub fn drain_mailbox(
&mut self,
caller_cpu: usize,
target_cpu: usize,
) -> Result<(), RuntimeError> {
Self::valid_cpu(caller_cpu)?;
Self::valid_cpu(target_cpu)?;
self.queues
.drain_mailbox(caller_cpu, target_cpu)
.map(|_| ())
.map_err(Into::into)
}
pub fn run_next(&mut self, cpu: usize) -> Result<TaskToken, RuntimeError> {
Self::valid_cpu(cpu)?;
if self.current[cpu].is_some() {
return Err(RuntimeError::CurrentAlreadyOwned);
}
if self.state[cpu] != CpuState::Idle {
return Err(RuntimeError::InvalidStateTransition);
}
let task = self.queues.take_local(cpu).map_err(RuntimeError::from)?;
self.current[cpu] = Some(task);
self.state[cpu] = CpuState::Running;
Ok(task)
}
pub fn enter_exception(
&mut self,
cpu: usize,
generation: u64,
) -> Result<ExceptionFrame, RuntimeError> {
Self::valid_cpu(cpu)?;
if self.state[cpu] != CpuState::Running {
return Err(RuntimeError::ExceptionWhileNotRunning);
}
let task = self.current[cpu].ok_or(RuntimeError::ExceptionWhileNotRunning)?;
let frame = ExceptionFrame {
task_id: task.id,
owner_cpu: cpu,
generation,
};
self.queues.enter_exception(cpu, frame)?;
self.state[cpu] = CpuState::InException;
Ok(frame)
}
pub fn leave_exception(&mut self, cpu: usize) -> Result<ExceptionFrame, RuntimeError> {
Self::valid_cpu(cpu)?;
if self.state[cpu] != CpuState::InException {
return Err(RuntimeError::ReturnWhileNotInException);
}
let frame = self.queues.leave_exception(cpu)?;
let task = self.current[cpu].ok_or(RuntimeError::NoCurrentTask)?;
if frame.task_id != task.id || frame.owner_cpu != cpu {
return Err(RuntimeError::WrongCurrentTask);
}
self.state[cpu] = CpuState::Running;
Ok(frame)
}
pub fn return_current_to_idle(&mut self, cpu: usize) -> Result<TaskToken, RuntimeError> {
Self::valid_cpu(cpu)?;
if self.state[cpu] != CpuState::Running {
return Err(RuntimeError::NoCurrentTask);
}
let task = self.current[cpu]
.take()
.ok_or(RuntimeError::NoCurrentTask)?;
self.state[cpu] = CpuState::Idle;
Ok(task)
}
pub fn enter_wfi(&mut self, cpu: usize) -> Result<(), RuntimeError> {
Self::valid_cpu(cpu)?;
if self.current[cpu].is_some() || self.state[cpu] == CpuState::Running {
return Err(RuntimeError::WfiWhileRunning);
}
if self.state[cpu] != CpuState::Idle {
return Err(RuntimeError::InvalidStateTransition);
}
if self.queues.queue_len(cpu)? != 0 {
return Err(RuntimeError::WfiWithRunnableTask);
}
self.queues.enter_wfi(cpu)?;
self.state[cpu] = CpuState::Wfi;
Ok(())
}
pub fn state(&self, cpu: usize) -> Result<CpuState, RuntimeError> {
Self::valid_cpu(cpu)?;
Ok(self.state[cpu])
}
pub fn current(&self, cpu: usize) -> Result<Option<TaskToken>, RuntimeError> {
Self::valid_cpu(cpu)?;
Ok(self.current[cpu])
}
pub fn queue_len(&self, cpu: usize) -> Result<usize, RunQueueError> {
self.queues.queue_len(cpu)
}
}snippet sha256: ed63df29b89f…file sha256: 4bb8d6cdea8b…
02 · Doğrulayan test kodu
Operations komutuna bağlı focused test
tam Rust öğesiL128–L145
simulation/tests/g8i_dormant_runtime.rs::current_task_returns_to_idle_only_after_running_state
#[test]
fn current_task_returns_to_idle_only_after_running_state() {
let mut runtime = DormantG8iRuntime::new();
assert_eq!(
runtime.return_current_to_idle(0),
Err(RuntimeError::NoCurrentTask)
);
let task = TaskToken {
id: 25,
owner_cpu: 0,
};
runtime.publish_local(0, task).unwrap();
runtime.run_next(0).unwrap();
assert_eq!(runtime.return_current_to_idle(0).unwrap(), task);
assert_eq!(runtime.state(0), Ok(CpuState::Idle));
assert_eq!(runtime.current(0), Ok(None));
}snippet sha256: 11dddb23cbd8…file sha256: 0d6a95bebab7…
03 · Kapı kimlik kaydı
Operations sıra, kimlik ve başlık bağı
tam Operations kaydıL23731–L23771
website/src/lib/operations.ts::g8i-dormant-runtime-model-partial
{
id: "g8i-dormant-runtime-model-partial",
date: "2026-08-24",
sequence: 156,
status: "passed",
umbrella_status: "partial",
title: "G8i: dormant per-CPU runtime model",
summary:
"S156, S155 ownership modelini dormant runtime state machine ile tüketerek dört CPU için Idle/Running/InException/Wfi durumlarını, local dequeue, global tekil current-task sahipliğini, exact exception frame dönüşünü, quiescent WFI wake/admission'ı ve target mailbox drain öncesi remote task'in runnable olmamasını 8/8 kapattı. Bu kaynak/model kabulüdür; production scheduler wiring, QEMU ve fiziksel runtime açılmadı.",
evidence: [
"g8i_dormant_runtime: 8/8 PASS; dört CPU idle başlangıcı, owner-local dequeue, tekil current slot, exception entry/return, current→idle ve quiescent WFI doğrulandı.",
"Remote task, target mailbox drain edilene kadar queue'da runnable değildir; running CPU WFI'ya giremez ve current olmadan exception entry reddedilir.",
"Runnable queue ve tekrar WFI fail-closed reddediliyor; local/remote publish WFI hedefini Idle'a uyandırıyor, foreign drain reddediliyor ve geçersiz CPU public API'lerde panic yerine InvalidCpu döndürüyor.",
"Current task kimliği bütün CPU'larda global tekildir; current durumundaki task başka queue/mailbox'a yeniden yayınlanamaz.",
"Kalıcı kapsam: `docs/M8.1-RPi5-G8i-Dormant-Runtime-Model-Proof.md`.",
"S156 fiziksel/device operasyonu yapmadı: physical/device operations=0 ve RUNBOOK_EXECUTED_IN_S156=NO.",
],
commands: [
"cargo test -p aselsan_microkernel_simulation --test g8i_dormant_runtime -- --test-threads=1",
],
terminalSessions: [
{
id: "s156-g8i-dormant-runtime-model",
title: "G8i dormant runtime host model kapısı",
commandLines: [
"cargo test -p aselsan_microkernel_simulation --test g8i_dormant_runtime -- --test-threads=1",
],
outputLines: ["running 8 tests", "test result: ok. 8 passed; 0 failed"],
exitCode: 0,
outputMode: "selected",
},
],
terminalSessionsNote:
"S156 yalnız bounded host/model state machine'dir; production scheduler, exception assembly, context switch, QEMU, fiziksel RPi ve generic SMP runtime sonucu değildir.",
limitations: [
"Production scheduler current-task ve per-CPU queue wiring'i henüz açılmadı; bu kapı model/source sınırındadır.",
"Gerçek per-CPU IRQ stack, exception-frame trampoline, context switch ve migration sonraki G8i runtime kapılarında açılmalıdır.",
"QEMU, fiziksel/device operations, CPU hotplug, TLB shootdown, long soak ve generic SMP arbitration kapsam dışıdır.",
"Fiziksel/device operations=0; RUNBOOK_EXECUTED_IN_S156=NO.",
],
},snippet sha256: 261ec1e89b01…file sha256: 9726dbf00f84…
Focused test komutu
cargo test -p aselsan_microkernel_simulation --test g8i_dormant_runtime -- --test-threads=1Registry schema v5 · generator
website/scripts/generate-code-gates.mjs · Tam SHA-256: 3050638b71a684d8f8f947a8a6faa237a17fa8db5dc0db04fb207b668b462af9