mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
Replace the state-relabel-only round-robin with the SUB-OS "Weave" scheduler backed by a genuine callee-saved context switch. Threads now actually run on their own kernel stacks instead of merely having their state field rewritten. What was implemented: - sub_ctx_switch(): per-arch assembly (arch/x86_64/cpu/switch.asm, arch/aarch64/cpu/switch.S, arch/armv8i/cpu/switch.S) that saves/restores the callee-saved register set (+ flags on x86_64) on each thread's own stack, plus a first-run trampoline (sub_thread_trampoline) that launches a freshly forged thread frame with entry/arg in callee-saved registers. - task_forge_frame(): builds the initial saved-context frame per arch so the very first switch into a new thread lands on the trampoline; task_t gains a pointer-sized ctx_sp so the same struct works on 64- and 32-bit. - Weave policy (kernel/sched.c): WEAVE_NLANES priority lanes, always dispatch the lowest non-empty lane round-robin; a task that yields voluntarily is woven UP a lane (interactive), one preempted after burning its quantum is woven DOWN (CPU-bound). Cooperative switching (sched_yield / task_exit) is always live; timer-driven preemption is gated behind sched_set_preempt() and left disarmed for now. - task_exit() now switches to the next runnable thread via sched_exit_current() instead of spinning/halting. - Boot-time weave_selftest() (x86_64) and sched_dump() diagnostics. How it was verified: - Builds clean for all three targets: x86_64 (CROSS_COMPILE=x86_64-linux-gnu-, RUSTC="rustc --target x86_64-unknown-none"), aarch64, armv8i. No new warnings; the new x86_64 asm carries a .note.GNU-stack section. - Booted x86_64 under QEMU (TCG): the self-test runs three cooperative kernel threads to completion on separate stacks with the expected 1->2->3 round-robin interleave, reports "20 real context switches, 3/3 workers exited", returns cleanly to the boot thread, and boot proceeds normally to ring-3 init and the shell. No fault/panic. Left unverified: - The aarch64/armv8i sub_ctx_switch frames build and link but are not yet boot-tested on their QEMU targets (tracked in docs/AUTODEV_ROADMAP.md). - Timer preemption path is implemented but disarmed; exited kernel threads currently leak their stack (reaper is next in the backlog). Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Jk6K69yGS7zYgvoWd6nJxQ
50 lines
1.6 KiB
ArmAsm
50 lines
1.6 KiB
ArmAsm
/*
|
|
* SUB-OS kernel context switch (AArch64)
|
|
* --------------------------------------
|
|
* void sub_ctx_switch(void** save_sp, void* load_sp)
|
|
* x0 = save_sp, x1 = load_sp
|
|
*
|
|
* Saves the AAPCS64 callee-saved registers (x19-x28) plus the frame pointer
|
|
* (x29) and link register (x30) of the outgoing thread, records its stack
|
|
* pointer through *save_sp, then adopts the incoming thread's stack and
|
|
* restores the mirror image. Returns into whoever is switched in.
|
|
*
|
|
* NOTE: implemented for parity with x86_64 and to keep the shared scheduler
|
|
* building on this target; not yet exercised on hardware/QEMU for aarch64.
|
|
*/
|
|
|
|
.text
|
|
.globl sub_ctx_switch
|
|
.globl sub_thread_trampoline
|
|
|
|
sub_ctx_switch:
|
|
sub sp, sp, #(12 * 8)
|
|
stp x19, x20, [sp, #0]
|
|
stp x21, x22, [sp, #16]
|
|
stp x23, x24, [sp, #32]
|
|
stp x25, x26, [sp, #48]
|
|
stp x27, x28, [sp, #64]
|
|
stp x29, x30, [sp, #80] /* fp, lr */
|
|
|
|
mov x2, sp
|
|
str x2, [x0] /* *save_sp = outgoing SP */
|
|
mov sp, x1 /* adopt incoming SP */
|
|
|
|
ldp x19, x20, [sp, #0]
|
|
ldp x21, x22, [sp, #16]
|
|
ldp x23, x24, [sp, #32]
|
|
ldp x25, x26, [sp, #48]
|
|
ldp x27, x28, [sp, #64]
|
|
ldp x29, x30, [sp, #80]
|
|
add sp, sp, #(12 * 8)
|
|
ret
|
|
|
|
/* Fresh-thread trampoline: x19 = entry, x20 = argument (forged by task_create). */
|
|
sub_thread_trampoline:
|
|
mov x0, x20 /* arg */
|
|
blr x19 /* entry(arg) */
|
|
mov x0, #0
|
|
bl task_exit
|
|
1: wfi
|
|
b 1b
|