From de8ee60ecb4396fa0567db666f99c1b8d1114bc7 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Tue, 21 Apr 2026 23:03:49 +0800 Subject: feat: Add documentation for atomic operations and memory order, standardize lock-free programming requirements --- docs/specs/00_conventions.md | 3 +- docs/specs/atomics.md | 80 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 docs/specs/atomics.md diff --git a/docs/specs/00_conventions.md b/docs/specs/00_conventions.md index 91b98c9..c7e41c9 100644 --- a/docs/specs/00_conventions.md +++ b/docs/specs/00_conventions.md @@ -230,8 +230,10 @@ Phase 2 全部完成后,从各 spec 中提取汇总为 `docs/specs/lock_orderi ### 5.3 原子操作 - 引用计数(`refcount`)使用 `__atomic_fetch_sub` / `__atomic_fetch_add` + `__ATOMIC_ACQ_REL` +- **[强制]** 所有在多核间无锁共享的数据,必须使用 `lume::atomic` 类型封装,并显式指定内存序。 - Spinlock 的 acquire/release 内含隐式 fence,临界区内无需额外屏障 - **禁止** 用裸 `volatile` 替代原子操作 +- **禁止** 在代码中直接使用 `__atomic_*` 内建函数,必须通过 `lume::atomic` 包装器。 --- @@ -364,4 +366,3 @@ $(BUILD)/%.o: %.S | `make fmt` | `clang-format -i` 格式化所有源文件 | | `make lint` | `clang-tidy` 静态分析 | | `make test` | QEMU 无头冒烟测试 (Phase 4) | - diff --git a/docs/specs/atomics.md b/docs/specs/atomics.md new file mode 100644 index 0000000..841f287 --- /dev/null +++ b/docs/specs/atomics.md @@ -0,0 +1,80 @@ +# 原子操作与内存序 (Atomics & Memory Ordering) + +## 1. 目标 (Objective) + +为 LumeOS 在 RISC-V 弱内存模型 (RVWMO) 环境下提供一套安全、可控的原子操作库。本模块旨在通过封装 C++ `std::atomic` 风格的接口,强制开发者在进行无锁编程时显式考虑内存序 (Memory Ordering),以避免因指令重排导致的、难以复现的并发 Bug。 + +## 2. 前置依赖 (Dependencies) + +- **编译器支持:** 依赖 GCC/Clang 的 `__atomic_*` 内建函数。 + +## 3. 核心设计:`lume::atomic` + +### 3.1 问题背景:弱内存模型 (RVWMO) + +RISC-V 采用弱内存模型,允许 CPU 和编译器进行激进的指令重排。在无锁数据结构(如 Per-CPU 缓存的无锁链表)中,如果仅使用简单的原子操作而没有指定正确的内存序,可能发生以下灾难: + +- **场景:** CPU A 分配一个新节点 `node`,填充其数据 `node->data = val`,然后通过原子交换将其链接到链表头 `head.exchange(node)`。 +- **风险:** CPU B 可能先观测到 `head` 指针的更新,但由于指令重排,`node->data` 的写入尚未对 CPU B 可见,导致 CPU B 读取到未初始化的垃圾数据。 + +`Spinlock` 内部的 `fence` 无法保护这种无锁路径。 + +### 3.2 解决方案:封装 `std::atomic` 风格接口 + +LumeOS 将提供 `lume::atomic` 模板类,禁止直接使用 `__atomic_*` 内建函数。 + +1. **定义 `memory_order` 枚举:** + ```cpp + // in include/lume/atomic.h + namespace lume { + enum memory_order { + relaxed = __ATOMIC_RELAXED, + consume = __ATOMIC_CONSUME, + acquire = __ATOMIC_ACQUIRE, + release = __ATOMIC_RELEASE, + acq_rel = __ATOMIC_ACQ_REL, + seq_cst = __ATOMIC_SEQ_CST + }; + } + ``` + +2. **创建 `lume::atomic` 模板类:** + ```cpp + // in include/lume/atomic.h + namespace lume { + template + struct atomic { + T value; + + T load(memory_order order = seq_cst) const { + return __atomic_load_n(&value, order); + } + + void store(T desired, memory_order order = seq_cst) { + __atomic_store_n(&value, desired, order); + } + + T fetch_add(T arg, memory_order order = seq_cst) { + return __atomic_fetch_add(&value, arg, order); + } + // ... 其他 fetch_*, exchange, compare_exchange_strong 等方法 + }; + } + ``` + +3. **强制使用规范:** + 在 `00_conventions.md` 中明确规定:所有在多核间无锁共享的数据(如 `Frame::refcount`,PCP 链表头指针),其类型**必须**是 `lume::atomic`,严禁使用原生类型或 `volatile`。 + + **示例 (PMM):** + ```cpp + // in mm/frame.h + #include + struct Frame { + lume::atomic refcount; + // ... + }; + ``` + +## 4. 公共 API + +`lume::atomic` 的 API 设计将严格对齐 C++ 标准库的 `std::atomic`,降低学习成本。 \ No newline at end of file -- cgit v1.2.3