Skip to content

第二十二周工作总结

概述

本周启动了项目重写,将原 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.rsPriority newtype(封装 usize),反转序:数值越小优先级越高,Ord impl 翻转使 > 表示更高优先级
  • util.rsUninitCell<T>MaybeUninit<UnsafeCell<T>>),一次性写入的延迟初始化容器,用于 TaskStorage 中 Future 的静态存储

任务状态机与存储

modules/executor/src/task/ 下:

  • state.rs — 任务状态原子变量,两个独立 bit flag:STATE_SPAWNED(已派发)和 STATE_RUN_QUEUED(在运行队列中)
  • storage.rsTaskStorage<F>,任务的静态存储单元,持有 Future + 状态 + 链表指针
  • header.rsTaskInfo(类型擦除的任务头)和 TaskRefNonNull<TaskInfo> 封装),供 RunQueue 和 Waker 操作
  • run_queue.rsRunQueue,基于 cordyceps::List 的侵入式双向链表 FIFO 运行队列
  • waker.rs — 基于 TaskRefRawWaker / RawWakerVTable 实现,唤醒时调用 wake_task 将任务重新入队

Executor 与 Spawner

  • executor.rs — 单优先级 Executor,轮询 RunQueue 中的就绪 Future,通过 BitmapOps 回调与全局位图交互
  • spawner.rsSpawner<N> 全局调度器,核心设计:
    • executors: [Executor; N] — 每个优先级一个 Executor
    • prio_stack — LIFO 优先级栈,记录当前占据系统栈空间的 executor(栈顶 = 当前运行)
    • try_preempt() — 读取位图最高优先级与栈顶比较,更高则 push 并返回 RunToken
    • run() / 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/