Skip to content

parse the timer interrupt only once#2555

Open
stlankes wants to merge 1 commit into
hermit-os:mainfrom
stlankes:timer
Open

parse the timer interrupt only once#2555
stlankes wants to merge 1 commit into
hermit-os:mainfrom
stlankes:timer

Conversation

@stlankes

@stlankes stlankes commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

init() (boot core) and init_cpu() (application processors) both parsed the "arm,armv8-timer" node of the device tree to find the timer interrupt, and each picked its own triplet out of the four the node lists. The timer is a PPI, so every core enables it in its own redistributor — if the two parsers ever disagree about which interrupt the kernel uses, the application processors enable an interrupt that never fires and tasks sleeping on them are not woken up again.

Parse the node once in init(), cache the interrupt and its trigger mode, and let both callers enable it from there. No functional change: both sites selected the Non-secure Phys timer before.

@stlankes
stlankes requested a review from mkroening July 15, 2026 13:33
@stlankes
stlankes force-pushed the timer branch 2 times, most recently from 554e158 to ffa7cdc Compare July 15, 2026 13:51

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark Results

Details
Benchmark Current: d7bafe7 Previous: 2e23902 Performance Ratio
startup_benchmark Build Time 82.09 s 80.34 s 1.02
startup_benchmark File Size 0.80 MB 0.80 MB 1.00
Startup Time - 1 core 0.74 s (±0.03 s) 0.75 s (±0.02 s) 1.00
Startup Time - 2 cores 0.75 s (±0.02 s) 0.74 s (±0.02 s) 1.01
Startup Time - 4 cores 0.76 s (±0.02 s) 0.74 s (±0.02 s) 1.03
multithreaded_benchmark Build Time 83.62 s 82.11 s 1.02
multithreaded_benchmark File Size 0.86 MB 0.86 MB 1.00
Multithreaded Pi Efficiency - 2 Threads 86.65 % (±7.73 %) 85.89 % (±6.61 %) 1.01
Multithreaded Pi Efficiency - 4 Threads 43.06 % (±2.87 %) 43.43 % (±2.56 %) 0.99
Multithreaded Pi Efficiency - 8 Threads 25.25 % (±1.80 %) 25.76 % (±1.53 %) 0.98
micro_benchmarks Build Time 81.67 s 80.40 s 1.02
micro_benchmarks File Size 0.86 MB 0.86 MB 1.00
Scheduling time - 1 thread 62.63 ticks (±3.13 ticks) 62.65 ticks (±4.06 ticks) 1.00
Scheduling time - 2 threads 35.09 ticks (±5.07 ticks) 34.08 ticks (±4.10 ticks) 1.03
Micro - Time for syscall (getpid) 3.32 ticks (±0.48 ticks) 3.45 ticks (±0.58 ticks) 0.96
Memcpy speed - (built_in) block size 4096 79678.63 MByte/s (±55361.21 MByte/s) 82448.38 MByte/s (±56997.13 MByte/s) 0.97
Memcpy speed - (built_in) block size 1048576 30459.20 MByte/s (±24552.11 MByte/s) 30585.98 MByte/s (±24707.84 MByte/s) 1.00
Memcpy speed - (built_in) block size 16777216 26391.51 MByte/s (±21772.32 MByte/s) 26340.06 MByte/s (±21720.96 MByte/s) 1.00
Memset speed - (built_in) block size 4096 79817.52 MByte/s (±55466.35 MByte/s) 82292.76 MByte/s (±56891.50 MByte/s) 0.97
Memset speed - (built_in) block size 1048576 31207.35 MByte/s (±24994.94 MByte/s) 31323.85 MByte/s (±25145.86 MByte/s) 1.00
Memset speed - (built_in) block size 16777216 27145.54 MByte/s (±22248.56 MByte/s) 27104.68 MByte/s (±22209.94 MByte/s) 1.00
Memcpy speed - (rust) block size 4096 74870.34 MByte/s (±51991.06 MByte/s) 74097.96 MByte/s (±51811.44 MByte/s) 1.01
Memcpy speed - (rust) block size 1048576 30226.92 MByte/s (±24529.53 MByte/s) 30361.60 MByte/s (±24602.37 MByte/s) 1.00
Memcpy speed - (rust) block size 16777216 26867.44 MByte/s (±22144.91 MByte/s) 27625.34 MByte/s (±22806.88 MByte/s) 0.97
Memset speed - (rust) block size 4096 75304.73 MByte/s (±52305.27 MByte/s) 74373.47 MByte/s (±51976.48 MByte/s) 1.01
Memset speed - (rust) block size 1048576 30960.17 MByte/s (±24946.64 MByte/s) 31110.89 MByte/s (±25033.24 MByte/s) 1.00
Memset speed - (rust) block size 16777216 27635.09 MByte/s (±22624.95 MByte/s) 28386.93 MByte/s (±23265.03 MByte/s) 0.97
alloc_benchmarks Build Time 75.96 s 74.76 s 1.02
alloc_benchmarks File Size 0.87 MB 0.87 MB 1.00
Allocations - Allocation success 91.31 % 91.31 % 1
Allocations - Deallocation success 100.00 % 100.00 % 1
Allocations - Pre-fail Allocations 61.44 % 61.44 % 1
Allocations - Average Allocation time 7897.94 Ticks (±132.95 Ticks) 5860.58 Ticks (±98.43 Ticks) 1.35
Allocations - Average Allocation time (no fail) 8430.56 Ticks (±126.56 Ticks) 6554.81 Ticks (±92.86 Ticks) 1.29
Allocations - Average Deallocation time 1496.32 Ticks (±367.78 Ticks) 1805.01 Ticks (±250.35 Ticks) 0.83
mutex_benchmark Build Time 75.83 s 79.82 s 0.95
mutex_benchmark File Size 0.86 MB 0.86 MB 1.00
Mutex Stress Test Average Time per Iteration - 1 Threads 12.04 ns (±0.34 ns) 12.10 ns (±0.41 ns) 1.00
Mutex Stress Test Average Time per Iteration - 2 Threads 41.84 ns (±2.38 ns) 40.26 ns (±1.68 ns) 1.04

This comment was automatically generated by workflow using github-action-benchmark.

init() (boot core) and init_cpu() (application processors) both parsed
the "arm,armv8-timer" node of the device tree to find the timer
interrupt, and each picked its own triplet out of the four the node
lists. The timer is a PPI, so every core enables it in its own
redistributor — if the two parsers ever disagree about which interrupt
the kernel uses, the application processors enable an interrupt that
never fires and tasks sleeping on them are not woken up again.

Parse the node once in init(), cache the interrupt and its trigger mode,
and let both callers enable it from there. No functional change: both
sites selected the Non-secure Phys timer before.
@stlankes stlankes changed the title enable the virtual timer interrupt on application processors parse the timer interrupt only once Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants