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 在 进程宏 中
每月2,119 次下载
用于 percpu
18KB
318 行
percpu
定义和访问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