#arceos #define #access #structure #data #percpu #per-cpu

nightly macro no-std percpu_macros

宏用于定义和访问per-CPU数据结构

5个版本

0.1.4 2024年8月11日
0.1.3 2024年7月26日
0.1.2 2024年7月17日
0.1.1 2024年7月15日
0.1.0 2024年7月15日

1588进程宏

Download history 328/week @ 2024-07-13 468/week @ 2024-07-20 951/week @ 2024-07-27 188/week @ 2024-08-03 450/week @ 2024-08-10

每月2,119 次下载
用于 percpu

GPL-3.0-or-later OR Apache-2…

18KB
318

percpu

Crates.io Docs.rs CI

定义和访问per-CPU数据结构。

所有per-CPU数据都放置在几个连续的内存区域中,称为per-CPU数据区域,其数量与CPU的数量相同。每个CPU都有自己的per-CPU数据区域。在初始化时,特定于架构的线程指针寄存器(例如,x86_64上的GS_BASE)被设置为该区域的基址。

在访问当前CPU上的per-CPU数据时,首先使用线程指针寄存器获取相应的per-CPU数据区域,然后添加偏移量以访问相应的字段。

示例

#[percpu::def_percpu]
static CPU_ID: usize = 0;

// initialize per-CPU data for 4 CPUs.
percpu::init(4);
// set the thread pointer register to the per-CPU data area 0.
percpu::set_local_thread_pointer(0);

// access the per-CPU data `CPU_ID` on the current CPU.
println!("{}", CPU_ID.read_current()); // prints "0"
CPU_ID.write_current(1);
println!("{}", CPU_ID.read_current()); // prints "1"

目前,您需要手动修改链接脚本,将以下行添加到您的链接脚本中

. = ALIGN(4K);
_percpu_start = .;
.percpu 0x0 (NOLOAD) : AT(_percpu_start) {
    _percpu_load_start = .;
    *(.percpu .percpu.*)
    _percpu_load_end = .;
    . = _percpu_load_start + ALIGN(64) * CPU_NUM;
}
. = _percpu_start + SIZEOF(.percpu);

Cargo功能

  • sp-naive:用于单核使用。在这种情况下,每个per-CPU数据只是一个全局变量,不使用特定于架构的线程指针寄存器。
  • preempt:用于可抢占系统使用。在这种情况下,我们需要在访问per-CPU数据时禁用抢占。否则,当数据正在被访问且当前线程发生抢占时,数据可能会损坏。
  • arm-el2:用于在ARM系统上运行的EL2使用(例如虚拟机管理程序)。在这种情况下,我们使用TPIDR_EL2而不是TPIDR_EL1来存储per-CPU数据区域的基址。

RISC-V注意

由于RISC-V不提供用户和内核模式的单独线程指针寄存器,我们暂时使用gp寄存器指向per-CPU数据区域,而tp寄存器用于线程局部存储。

依赖项

~260–710KB
~17K SLoC