kernel::spawn
Task creation and stack allocation (plan W1.3, W0.1).
Stacks are bump-allocated from the linker-defined task_stacks region
(_task_stack_start/_task_stack_end) — no magic addresses. Each task’s
initial TaskContext is built so the first dispatch (rfe in the trap
handler) lands at the entry point with a clean single register window.
StackSource
Section titled “StackSource”enum StackSource { Pool, Heap,}Where a new task’s stack comes from.
Implements: Clone, Copy, Eq, PartialEq, StructuralPartialEq
Functions
Section titled “Functions”stack_guard_intact
Section titled “stack_guard_intact”fn stack_guard_intact(stack_base: u32, stack_size: u32) -> boolTrue if tcb’s stack guard is still intact.
A false return means the task has already written past the bottom of its
stack and has corrupted whatever lies below. Tasks with stack_size == 0
(the idle task, which runs on the boot stack) are always reported intact.
sys_spawn
Section titled “sys_spawn”fn sys_spawn(name: &'static str, entry: fn(..), priority: hal::types::Priority, stack_size: usize) -> Option<hal::types::TaskId>Kernel-internal spawn. Returns None if no TCB slot or stack is available.
sys_spawn_from
Section titled “sys_spawn_from”fn sys_spawn_from(name: &'static str, entry: fn(..), priority: hal::types::Priority, stack_size: usize, affinity: scheduler::Affinity, stack: StackSource) -> Option<hal::types::TaskId>Spawn with an explicit stack source.
Safety of the Heap variant
Section titled “Safety of the Heap variant”The caller must delete the task through dynobj::delete_task, which is
what returns the stack. Letting a heap-backed task simply run off the end
of its entry point leaks the stack exactly as the pool would.
References: Affinity, Priority, StackSource, TaskId
sys_spawn_with_affinity
Section titled “sys_spawn_with_affinity”fn sys_spawn_with_affinity(name: &'static str, entry: fn(..), priority: hal::types::Priority, stack_size: usize, affinity: scheduler::Affinity) -> Option<hal::types::TaskId>Spawn with an explicit core affinity.
Affinity::Any is what sys_spawn passes and what most tasks want.
Pinning is for a task that cannot float: a driver whose peripheral
interrupt is routed to one core’s matrix, or work with a timing budget that
a migration would blow.
References: Affinity, Priority, TaskId
Constants
Section titled “Constants”STACK_GUARD
Section titled “STACK_GUARD”const STACK_GUARD: u32;Written at the lowest address of every task stack and checked on each context switch. Stack growth is downward, so this word is the first thing an overflow destroys.