arceos-affinity
路径:
test-suit/arceos/task/affinity类型:测试入口 crate 分层:测试层 / ArceOS 任务调度回归 版本:0.1.0文档依据:Cargo.toml、src/main.rs、qemu-riscv64.toml、docs/arceos-guide.md
arceos-affinity 是一个专门验证“当前任务 CPU 亲和性设置与迁移是否正确”的系统级回归入口。它通过批量创建任务、设置单核亲和掩码、循环 yield_now() 并检查当前 CPU ID,来确认 ax-task 的亲和性语义没有回退。
它的核心边界非常明确:这不是 CPU 亲和性管理库,也不是通用并发框架;它只是拿 ax_set_current_affinity() 这条真实调用链做回归验证。
架构设计
1.1 测试场景结构
源码只有一个 main(),但内部场景分成两段:
- 为每个任务设置“只允许运行在某一个 CPU 上”的单点亲和性。
- 如果系统可见 CPU 数大于 1,再把该 CPU 从可运行集合中移除,验证任务能迁移到别的 CPU。
其中三个关键常量是:
NUM_TASKS = 10NUM_TIMES = 100FINISHED_TASKS:主线程等待所有任务结束的原子计数器
1.2 真实调用关系
这条链路不是伪造的测试桩,而是直接打到 ArceOS 真实任务栈:
关键点在于 ax-task::set_current_affinity() 并不只是记录一个掩码;在开启 SMP 时,如果当前 CPU 不再满足亲和性,它会立刻走迁移路径。
1.3 feature 与调度器关系
Cargo.toml 中的:
sched-rrsched-cfs
会透传到 ax-std 对应的调度器 feature。这个 crate 本身并不强依赖某一种调度算法,但它确实依赖:
multitask- 可见 CPU 数
- 任务迁移语义
因此它验证的是“亲和性约束是否成立”,而不是“某个调度器策略是否更优”。
核心功能
2.1 测试内容
每个任务执行的核心逻辑如下:
- 根据任务编号选择一个目标 CPU。
- 调用
ax_set_current_affinity(AxCpuMask::one_shot(cpu_id))。 - 在 100 次循环中反复检查
this_cpu_id() == cpu_id,中间穿插thread::yield_now()。 - 若系统是多核,再构造“除原 CPU 外都可运行”的掩码,重新设置亲和性。
- 再次循环验证“当前 CPU 不应再等于原 cpu_id”。
2.2 为什么使用 yield_now()
如果任务设置完亲和性后一直独占执行,无法充分暴露调度和迁移中的错误。加入 yield_now() 后:
- 当前任务会主动让出 CPU
- 调度器会重新选择可运行任务
- 更容易暴露“亲和性未生效”“迁移后仍落回原 CPU”等问题
2.3 边界澄清
这个 crate 不负责:
- 管理其他任务的亲和性
- 提供面向应用的高级负载均衡策略
- 评估跨核性能收益
它只验证“当前任务设置亲和性后,运行位置是否真的受约束”。
依赖关系
直接依赖
ax-std(multitask):提供线程创建、yield_now()和 ArceOS 扩展任务 API 入口。
间接依赖
ax_api::task::ax_set_current_affinity:对上层暴露亲和性设置接口。ax-task::set_current_affinity:实际执行亲和性更新与迁移。ax-hal::percpu::this_cpu_id:用来观察当前任务实际落在哪个 CPU 上。
主要消费者
cargo arceos test qemu自动发现的任务回归集合。- 调整
ax-task、ax-cpumask、SMP 调度逻辑后的定向回归。