第二十二周工作总结
概述
本周启动了项目重写,将原 embassy_preempt 项目重命名为 rt-async,并从零重新设计了核心架构。新架构采用 共享系统栈 + 优先级抢占 模型,executor 切换复用 Rust 函数调用/返回语义,彻底消除了逐任务栈分配和传统上下文切换的开销。
从零完成了 executor 调度器的核心实现,包括优先级位图、任务状态机、Executor 运行循环、抢占式 Spawner,以及 RISC-V 裸机运行时。所有代码在 std 环境下通过基本验证。
核心工作
1. 项目重启与优先级位图
提交:9698910 fc8ad3e — 2026-04-23
项目从 embassy_preempt 重写为 rt-async,设计目标:
#![no_std]内核,纯 Rust 无 libc 依赖- 共享系统栈,executor 不分配独立栈
- 任务数量无上限
- O(1) 优先级调度
首先实现了两级优先级位图 PriorityBitmap<G>(modules/executor/src/priority_bitmap.rs),支持 G ∈ [1, 64],最多 4096 个优先级。highest() 通过两条 trailing_zeros() 指令单周期完成就绪查找。
2. Executor 核心调度器
提交:2f3b293 ef8df1d 3edaeaf d90d04e — 2026-04-29
分四个提交逐步构建了完整的调度器,架构详见技术文档「调度器设计」和「架构概览」。
基础类型层
modules/executor/src/ 下:
priority.rs—Prioritynewtype(封装usize),反转序:数值越小优先级越高,Ordimpl 翻转使>表示更高优先级util.rs—UninitCell<T>(MaybeUninit<UnsafeCell<T>>),一次性写入的延迟初始化容器,用于TaskStorage中 Future 的静态存储
任务状态机与存储
modules/executor/src/task/ 下:
state.rs— 任务状态原子变量,两个独立 bit flag:STATE_SPAWNED(已派发)和STATE_RUN_QUEUED(在运行队列中)storage.rs—TaskStorage<F>,任务的静态存储单元,持有 Future + 状态 + 链表指针header.rs—TaskInfo(类型擦除的任务头)和TaskRef(NonNull<TaskInfo>封装),供 RunQueue 和 Waker 操作run_queue.rs—RunQueue,基于cordyceps::List的侵入式双向链表 FIFO 运行队列waker.rs— 基于TaskRef的RawWaker/RawWakerVTable实现,唤醒时调用wake_task将任务重新入队
Executor 与 Spawner
executor.rs— 单优先级 Executor,轮询 RunQueue 中的就绪 Future,通过BitmapOps回调与全局位图交互spawner.rs—Spawner<N>全局调度器,核心设计:executors: [Executor; N]— 每个优先级一个 Executorprio_stack— LIFO 优先级栈,记录当前占据系统栈空间的 executor(栈顶 = 当前运行)try_preempt()— 读取位图最高优先级与栈顶比较,更高则 push 并返回 RunTokenrun()/complete_executor()— 运行/弹出 executor
共享系统栈的核心原理详见技术文档「共享系统栈」:抢占 = 在被抢占 executor 栈帧之上调用新 executor 的 run()(嵌套函数调用),返回 = run() 返回后栈帧自然销毁。
3. std 环境适配
提交:66a410b af2aa76 — 2026-04-30
- 将
critical-section/std改为可选 feature,no_std环境下使用平台实现 - 替换手动
ceil_div为标准库div_ceil
4. RISC-V 裸机运行时与平台 crate
提交:6333bce — 2026-05-01
新建 modules/platform/ crate,包含 riscv64-rt 运行时:
modules/platform/
├── archs/riscv64-rt/
│ ├── trap/ # Trap 入口汇编、TrapFrame 定义、trap_handler 分发
│ ├── handlers/ # Exception / Interrupt 默认处理
│ ├── start.rs # _start → __rust_main 入口
│ └── panic.rs # 裸机 panic handler
├── src/lib.rs # 公共接口
└── src/logger.rs # log 后端Trap 入口(trap/entry.rs)保存/恢复全部 callee-saved 寄存器,分发到 Rust trap_handler,是整个系统中唯一需要汇编的地方。
模块结构
rt-async/
├── modules/
│ ├── executor/ # 核心调度器
│ │ ├── spawner.rs # Spawner<N> 全局调度器
│ │ ├── executor.rs # Executor 单优先级执行器
│ │ ├── priority_bitmap.rs # O(1) 两级位图
│ │ └── task/ # TaskStorage、RunQueue、Waker
│ └── platform/ # RISC-V 运行时 + 平台抽象
└── apps/