Files
SUB-OS/include/kernel/task.h
T
Claude a14a7c79b0 feat(sched): Weave tiered scheduler with real kernel-thread context switching
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
2026-08-25 08:16:37 +00:00

60 lines
1.6 KiB
C

#ifndef _KERNEL_TASK_H
#define _KERNEL_TASK_H
#include "types.h"
#include <lib/list.h>
typedef enum {
TASK_STATE_READY,
TASK_STATE_RUNNING,
TASK_STATE_BLOCKED,
TASK_STATE_SLEEPING,
TASK_STATE_ZOMBIE,
TASK_STATE_DEAD
} task_state_t;
typedef struct task_struct {
pid_t pid;
pid_t ppid;
pid_t pgid;
char name[32];
task_state_t state;
uint64_t rsp;
uint64_t stack_base;
size_t stack_size;
uint64_t sleep_until_ticks;
int priority;
int time_slice;
int exit_code;
/* --- SUB-OS "Weave" scheduler context ---------------------------------
* ctx_sp is the saved stack pointer handed to sub_ctx_switch(); it is
* pointer-sized so the same struct works on 64- and 32-bit targets.
* A task lives in exactly one lane while it is runnable; weave_credit is
* the quantum it has left in that lane, and weave_on marks it as an active
* participant in the run rotation (so a bare kernel idle task that merely
* calls sched_yield() is never enqueued). */
void* ctx_sp;
uint32_t weave_lane;
uint32_t weave_credit;
uint64_t sched_runs;
uint8_t weave_on;
struct list_head list;
struct list_head all_list;
} task_t;
typedef void (*task_entry_fn_t)(void* arg);
void task_init_idle(void);
task_t* task_create(const char* name, task_entry_fn_t entry, void* arg, int priority);
void task_exit(int exit_code);
task_t* task_current(void);
pid_t task_get_pid(void);
void task_set_current(task_t* task);
task_t* task_find_by_pid(pid_t pid);
int task_kill(pid_t pid, int sig);
void task_dump_pstree(void);
#endif // _KERNEL_TASK_H