Skip to content

Commit c67ec15

Browse files
committed
perf(port_riscv): disable register preloading by default
Reduces the time taken to activate a task by 95–101 cycles (measured on FE310).
1 parent c762883 commit c67ec15

File tree

3 files changed

+39
-26
lines changed

3 files changed

+39
-26
lines changed

src/constance_port_riscv/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ repository = "https://github.com/yvt/Constance"
1111

1212
[features]
1313
emulate-lr-sc = []
14+
preload-registers = []
1415

1516
[dependencies]
1617
constance_portkit = { path = "../constance_portkit" }

src/constance_port_riscv/src/lib.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ The idle task (the implicit task that runs when `*`[`running_task_ptr`]`().is_no
151151

152152
[`running_task_ptr`]: constance::kernel::State::running_task_ptr
153153

154+
When a task is activated, a new context state is created inside the task's stack. By default, only essential registers are preloaded with known values. The **`preload-registers`** Cargo feature enables preloading for all `x` registers, which might help in debugging at the cost of performance and code size.
155+
154156
## Processor Modes
155157

156158
All code executes in Machine mode. The value of `mstatus.MPP` is always `M` (`0b11`).

src/constance_port_riscv/src/threading/imp.rs

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,8 @@ impl State {
592592
let mut sp = (stack as *mut u8).wrapping_add(stack.len()) as *mut MaybeUninit<u32>;
593593
// TODO: Enforce minimum stack size
594594

595+
let preload_all = cfg!(feature = "preload-registers");
596+
595597
// First-level state (always saved and restored as part of our exception
596598
// entry/return sequence)
597599
let first_level = unsafe {
@@ -602,24 +604,30 @@ impl State {
602604
// ra: The return address
603605
first_level[0] = MaybeUninit::new(System::exit_task as usize as u32);
604606
// t0-t2: Uninitialized
605-
first_level[1] = MaybeUninit::new(0x05050505);
606-
first_level[2] = MaybeUninit::new(0x06060606);
607-
first_level[3] = MaybeUninit::new(0x07070707);
607+
if preload_all {
608+
first_level[1] = MaybeUninit::new(0x05050505);
609+
first_level[2] = MaybeUninit::new(0x06060606);
610+
first_level[3] = MaybeUninit::new(0x07070707);
611+
}
608612
// a0: Parameter to the entry point
609613
first_level[4] = MaybeUninit::new(task.attr.entry_param as u32);
610614
// a1-a7: Uninitialized
611-
first_level[5] = MaybeUninit::new(0x11111111);
612-
first_level[6] = MaybeUninit::new(0x12121212);
613-
first_level[7] = MaybeUninit::new(0x13131313);
614-
first_level[8] = MaybeUninit::new(0x14141414);
615-
first_level[9] = MaybeUninit::new(0x15151515);
616-
first_level[10] = MaybeUninit::new(0x16161616);
617-
first_level[11] = MaybeUninit::new(0x17171717);
615+
if preload_all {
616+
first_level[5] = MaybeUninit::new(0x11111111);
617+
first_level[6] = MaybeUninit::new(0x12121212);
618+
first_level[7] = MaybeUninit::new(0x13131313);
619+
first_level[8] = MaybeUninit::new(0x14141414);
620+
first_level[9] = MaybeUninit::new(0x15151515);
621+
first_level[10] = MaybeUninit::new(0x16161616);
622+
first_level[11] = MaybeUninit::new(0x17171717);
623+
}
618624
// t3-t6: Uninitialized
619-
first_level[12] = MaybeUninit::new(0x28282828);
620-
first_level[13] = MaybeUninit::new(0x29292929);
621-
first_level[14] = MaybeUninit::new(0x30303030);
622-
first_level[15] = MaybeUninit::new(0x31313131);
625+
if preload_all {
626+
first_level[12] = MaybeUninit::new(0x28282828);
627+
first_level[13] = MaybeUninit::new(0x29292929);
628+
first_level[14] = MaybeUninit::new(0x30303030);
629+
first_level[15] = MaybeUninit::new(0x31313131);
630+
}
623631
// pc: The entry point
624632
first_level[16] = MaybeUninit::new(task.attr.entry_point as usize as u32);
625633

@@ -631,18 +639,20 @@ impl State {
631639
};
632640

633641
// s0-s12: Uninitialized
634-
extra_ctx[0] = MaybeUninit::new(0x08080808);
635-
extra_ctx[1] = MaybeUninit::new(0x09090909);
636-
extra_ctx[2] = MaybeUninit::new(0x18181818);
637-
extra_ctx[3] = MaybeUninit::new(0x19191919);
638-
extra_ctx[4] = MaybeUninit::new(0x20202020);
639-
extra_ctx[5] = MaybeUninit::new(0x21212121);
640-
extra_ctx[6] = MaybeUninit::new(0x22222222);
641-
extra_ctx[7] = MaybeUninit::new(0x23232323);
642-
extra_ctx[8] = MaybeUninit::new(0x24242424);
643-
extra_ctx[9] = MaybeUninit::new(0x25252525);
644-
extra_ctx[10] = MaybeUninit::new(0x26262626);
645-
extra_ctx[11] = MaybeUninit::new(0x27272727);
642+
if preload_all {
643+
extra_ctx[0] = MaybeUninit::new(0x08080808);
644+
extra_ctx[1] = MaybeUninit::new(0x09090909);
645+
extra_ctx[2] = MaybeUninit::new(0x18181818);
646+
extra_ctx[3] = MaybeUninit::new(0x19191919);
647+
extra_ctx[4] = MaybeUninit::new(0x20202020);
648+
extra_ctx[5] = MaybeUninit::new(0x21212121);
649+
extra_ctx[6] = MaybeUninit::new(0x22222222);
650+
extra_ctx[7] = MaybeUninit::new(0x23232323);
651+
extra_ctx[8] = MaybeUninit::new(0x24242424);
652+
extra_ctx[9] = MaybeUninit::new(0x25252525);
653+
extra_ctx[10] = MaybeUninit::new(0x26262626);
654+
extra_ctx[11] = MaybeUninit::new(0x27272727);
655+
}
646656

647657
let task_state = &task.port_task_state;
648658
unsafe { *task_state.sp.get() = sp as _ };

0 commit comments

Comments
 (0)