Skip to content

Commit 16f2b6c

Browse files
authored
Merge pull request rustsbi#42 from YdrMaster/main
refactor: 使用 fast-trap 重构以提高性能
2 parents 45a4d0f + a4d43a5 commit 16f2b6c

File tree

13 files changed

+824
-836
lines changed

13 files changed

+824
-836
lines changed

Cargo.lock

Lines changed: 19 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[workspace]
2-
members = ["rustsbi-qemu", "test-kernel", "bench-kernel", "xtask"]
2+
members = ["rustsbi-qemu", "hsm-cell", "test-kernel", "bench-kernel", "xtask"]
33
default-members = ["xtask"]

hsm-cell/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "hsm-cell"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
sbi-spec = "0.0.4"

hsm-cell/src/lib.rs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
//! 硬件线程状态和受状态保护的线程间共享数据。
2+
3+
#![no_std]
4+
#![deny(warnings, missing_docs)]
5+
6+
use core::{
7+
cell::UnsafeCell,
8+
hint::spin_loop,
9+
sync::atomic::{AtomicUsize, Ordering},
10+
};
11+
use sbi_spec::hsm::*;
12+
13+
/// 硬件线程状态和受状态保护的线程间共享数据。
14+
pub struct HsmCell<T> {
15+
status: AtomicUsize,
16+
val: UnsafeCell<Option<T>>,
17+
}
18+
19+
/// 当前硬件线程的共享对象。
20+
pub struct LocalHsmCell<'a, T>(&'a HsmCell<T>);
21+
22+
/// 任意硬件线程的共享对象。
23+
pub struct RemoteHsmCell<'a, T>(&'a HsmCell<T>);
24+
25+
unsafe impl<T: Send> Sync for HsmCell<T> {}
26+
unsafe impl<T: Send> Send for HsmCell<T> {}
27+
28+
const HART_STATE_START_PENDING_EXT: usize = usize::MAX;
29+
30+
impl<T> HsmCell<T> {
31+
/// 创建一个新的共享对象。
32+
pub const fn new() -> Self {
33+
Self {
34+
status: AtomicUsize::new(HART_STATE_STOPPED),
35+
val: UnsafeCell::new(None),
36+
}
37+
}
38+
39+
/// 从当前硬件线程的状态中获取线程间共享对象。
40+
///
41+
/// # Safety
42+
///
43+
/// 用户需要确保对象属于当前硬件线程。
44+
#[inline]
45+
pub unsafe fn local(&self) -> LocalHsmCell<'_, T> {
46+
LocalHsmCell(self)
47+
}
48+
49+
/// 取出共享对象。
50+
#[inline]
51+
pub fn remote(&self) -> RemoteHsmCell<'_, T> {
52+
RemoteHsmCell(self)
53+
}
54+
}
55+
56+
impl<T> LocalHsmCell<'_, T> {
57+
/// 从启动挂起状态的硬件线程取出共享数据,并将其状态设置为启动,如果成功返回取出的数据,否则返回当前状态。
58+
#[inline]
59+
pub fn start(&self) -> Result<T, usize> {
60+
loop {
61+
match self.0.status.compare_exchange(
62+
HART_STATE_START_PENDING,
63+
HART_STATE_STARTED,
64+
Ordering::AcqRel,
65+
Ordering::Relaxed,
66+
) {
67+
Ok(_) => break Ok(unsafe { (*self.0.val.get()).take().unwrap() }),
68+
Err(HART_STATE_START_PENDING_EXT) => spin_loop(),
69+
Err(HART_STATE_SUSPENDED) => {
70+
self.0.status.store(HART_STATE_STARTED, Ordering::Relaxed);
71+
break Ok(unsafe { (*self.0.val.get()).take().unwrap() });
72+
}
73+
Err(s) => break Err(s),
74+
}
75+
}
76+
}
77+
78+
/// 关闭。
79+
#[inline]
80+
pub fn stop_pending(&self) {
81+
self.0
82+
.status
83+
.store(HART_STATE_STOP_PENDING, Ordering::Relaxed)
84+
}
85+
86+
/// 关闭。
87+
#[inline]
88+
pub fn stop(&self) {
89+
self.0.status.store(HART_STATE_STOPPED, Ordering::Release)
90+
}
91+
92+
/// 关闭。
93+
#[inline]
94+
pub fn suspend_non_retentive(&self, t: T) {
95+
unsafe { *self.0.val.get() = Some(t) };
96+
self.0.status.store(HART_STATE_SUSPENDED, Ordering::Relaxed)
97+
}
98+
99+
/// 关闭。
100+
#[inline]
101+
pub fn suspend(&self) {
102+
self.0.status.store(HART_STATE_SUSPENDED, Ordering::Relaxed)
103+
}
104+
105+
/// 关闭。
106+
#[inline]
107+
pub fn resume(&self) {
108+
self.0.status.store(HART_STATE_STARTED, Ordering::Relaxed)
109+
}
110+
}
111+
112+
impl<T> RemoteHsmCell<'_, T> {
113+
/// 向关闭状态的硬件线程传入共享数据,并将其状态设置为启动挂起,返回是否放入成功。
114+
#[inline]
115+
pub fn start(self, t: T) -> bool {
116+
if self
117+
.0
118+
.status
119+
.compare_exchange(
120+
HART_STATE_STOPPED,
121+
HART_STATE_START_PENDING_EXT,
122+
Ordering::Acquire,
123+
Ordering::Relaxed,
124+
)
125+
.is_ok()
126+
{
127+
unsafe { *self.0.val.get() = Some(t) };
128+
self.0
129+
.status
130+
.store(HART_STATE_START_PENDING, Ordering::Release);
131+
true
132+
} else {
133+
false
134+
}
135+
}
136+
137+
/// 取出当前状态。
138+
#[inline]
139+
pub fn sbi_get_status(&self) -> usize {
140+
match self.0.status.load(Ordering::Relaxed) {
141+
HART_STATE_START_PENDING_EXT => HART_STATE_START_PENDING,
142+
normal => normal,
143+
}
144+
}
145+
146+
/// 判断这个 HART 能否接收 IPI。
147+
#[inline]
148+
pub fn allow_ipi(&self) -> bool {
149+
matches!(
150+
self.0.status.load(Ordering::Relaxed),
151+
HART_STATE_STARTED | HART_STATE_SUSPENDED
152+
)
153+
}
154+
}

rustsbi-qemu/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@ uart_16550 = "0.2"
2626
rcore-console = "0.0.0"
2727
dtb-walker = "=0.2.0-alpha.3"
2828
qemu-exit = "3.0"
29+
30+
hsm-cell = { path = "../hsm-cell" }
31+
fast-trap = { git = "https://github.com/YdrMaster/fast-trap", rev = "ffb40e2", features = [
32+
"riscv-m",
33+
] }

rustsbi-qemu/build.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,25 @@ MEMORY {
1414
DRAM : ORIGIN = 0x80000000, LENGTH = 2M
1515
}
1616
SECTIONS {
17-
.text : ALIGN(4) {
17+
.text : {
1818
*(.text.entry)
1919
*(.text .text.*)
2020
} > DRAM
21-
.rodata : ALIGN(8) {
22-
srodata = .;
21+
.rodata : {
2322
*(.rodata .rodata.*)
2423
*(.srodata .srodata.*)
25-
. = ALIGN(8);
26-
erodata = .;
2724
} > DRAM
28-
.data : ALIGN(8) {
29-
sdata = .;
25+
.data : {
3026
*(.data .data.*)
3127
*(.sdata .sdata.*)
32-
. = ALIGN(8);
33-
edata = .;
3428
} > DRAM
35-
.bss (NOLOAD) : ALIGN(8) {
29+
.bss (NOLOAD) : {
3630
*(.bss.uninit)
31+
. = ALIGN(8);
3732
sbss = .;
3833
*(.bss .bss.*)
3934
*(.sbss .sbss.*)
35+
. = ALIGN(8);
4036
ebss = .;
4137
} > DRAM
4238
/DISCARD/ : {

rustsbi-qemu/src/clint.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#![allow(unused)]
2+
3+
use crate::trap_stack::remote_hsm;
14
use core::cell::UnsafeCell;
25
use rustsbi::{spec::binary::SbiRet, HartMask, Ipi, Timer};
36

@@ -6,9 +9,8 @@ pub(crate) struct Clint;
69
impl Ipi for Clint {
710
#[inline]
811
fn send_ipi(&self, hart_mask: HartMask) -> SbiRet {
9-
let hsm = crate::HSM.wait();
1012
for i in 0..crate::NUM_HART_MAX {
11-
if hart_mask.has_bit(i) && hsm.is_ipi_allowed(i) {
13+
if hart_mask.has_bit(i) && remote_hsm(i).map_or(false, |hsm| hsm.allow_ipi()) {
1214
msip::send(i);
1315
}
1416
}
@@ -33,7 +35,6 @@ pub(crate) fn init(base: usize) {
3335
unsafe { *BASE.get() = base };
3436
}
3537

36-
#[allow(unused)]
3738
pub mod mtime {
3839
#[inline]
3940
pub fn read() -> u64 {

0 commit comments

Comments
 (0)