Is your feature request related to a problem? Please describe.
The GCC RISC-V port saves and restores the complete integer context on every
machine-timer interrupt, even when xTaskIncrementTick() returns pdFALSE.
On this no-switch path, saving s0-s11 is unnecessary because the RISC-V ABI
requires the called C functions to preserve them.
Describe the solution you'd like
Keep the existing task-frame layout, but split integer context handling into
caller-saved and callee-saved parts:
- Save caller-saved registers on timer entry.
- Call
xTaskIncrementTick().
- On
pdFALSE, restore caller-saved registers and return.
- On
pdTRUE, save s0-s11 into their reserved frame slots before
vTaskSwitchContext(), then use the existing full restore path.
Other trap and yield paths remain unchanged. FPU, vector, and chip-specific
additional contexts retain their current behavior.
For RV64, the no-switch path avoids 12 sd and 12 ld instructions, reducing
stack traffic by 192 bytes per tick.
Describe alternatives you've considered
Keeping the current full save is simpler but performs unnecessary memory
traffic on the common no-switch path. A separate short interrupt frame would
require larger changes to the existing frame ABI.
Additional context
Validated with:
- QEMU M-mode: no-switch, task-switch, FPU, vector, additional-context, and
combined configurations.
- JH7110/U74 M-mode hardware: baseline and optimized versions both passed
single-task and two-task tests for 1,000,000 ticks.
- 10,000 hardware no-switch samples:
- median: 59 → 50 cycles
- mean: 155.281 → 144.746 cycles
P99 and maximum did not improve.
If the approach is acceptable, I can submit a focused two-commit PR:
a context-helper refactor followed by the timer-path optimization.
How many devices will this feature impact?
Generic GCC RISC-V M-mode port; currently validated on one JH7110 board.
What are your project timelines?
Implementation and validation are complete. A PR can be submitted after
maintainer feedback.
Is your feature request related to a problem? Please describe.
The GCC RISC-V port saves and restores the complete integer context on every
machine-timer interrupt, even when
xTaskIncrementTick()returnspdFALSE.On this no-switch path, saving
s0-s11is unnecessary because the RISC-V ABIrequires the called C functions to preserve them.
Describe the solution you'd like
Keep the existing task-frame layout, but split integer context handling into
caller-saved and callee-saved parts:
xTaskIncrementTick().pdFALSE, restore caller-saved registers and return.pdTRUE, saves0-s11into their reserved frame slots beforevTaskSwitchContext(), then use the existing full restore path.Other trap and yield paths remain unchanged. FPU, vector, and chip-specific
additional contexts retain their current behavior.
For RV64, the no-switch path avoids 12
sdand 12ldinstructions, reducingstack traffic by 192 bytes per tick.
Describe alternatives you've considered
Keeping the current full save is simpler but performs unnecessary memory
traffic on the common no-switch path. A separate short interrupt frame would
require larger changes to the existing frame ABI.
Additional context
Validated with:
combined configurations.
single-task and two-task tests for 1,000,000 ticks.
P99 and maximum did not improve.
If the approach is acceptable, I can submit a focused two-commit PR:
a context-helper refactor followed by the timer-path optimization.
How many devices will this feature impact?
Generic GCC RISC-V M-mode port; currently validated on one JH7110 board.
What are your project timelines?
Implementation and validation are complete. A PR can be submitted after
maintainer feedback.