Measured Results
All numbers below come from a runnable prototype: V1, V2 and V5 on an XC7K480T FPGA at 50 MHz, with 128 KiB of zero-wait-state SRAM and 256 KiB of flash emulated in SRAM. Binaries are GCC 15.2.0 -O3; every measurement is repeated 10 000 times. The baselines are a kernel-only path (KERNEL), an Intel-UINTR-style scheme that bypasses the kernel only for active processes (UINTR), and a minimal software prologue (SOFTWARE).
A conservative testbed
The zero-wait-state SRAM approximates ideal cache behaviour. On a real SoC with slower or external memory, the kernel path gets longer while the extension can sit in TCM — so the reported gains are conservative.
Raw latency
| Scheme | target running | target dormant |
|---|---|---|
| Kernel-mediated | >800 | >800 |
| Software fast path | 80 | 120 |
| DULI · V5 | 15 | 15 |
The distinguishing result is not the average — it is that the bar does not move. V1 and V2 stay below 50 cycles in both process states; V5 stays at 15. Every extension variant has near-zero variance between active and dormant targets, a property no baseline has: UINTR is fast only while the target is scheduled and falls back to the full kernel path otherwise.
Isolation holds under attack
Malicious handlers were registered and made to read foreign memory or loop forever. The three cases that matter all terminate the handler and return to the preempted context:
- a malicious handler preempting a user-level thread;
- a malicious handler preempting the kernel;
- a malicious handler preempting another user-level handler, including deep nesting after V5's register banks are exhausted.
Spatial violations are caught by the PMP; temporal violations by the budget counter. In the third case, V5 degrades to V2 latency rather than failing — temporal isolation still holds.
Motion control: pulse-train output
Pulse-train output (PTO) is the PLC/servo primitive that toggles an output pin from an interrupt with a computed period. It is the canonical test for deterministic jitter.
| Scheme | Max sustainable frequency | Jitter |
|---|---|---|
| KERNEL | lowest; unusable above ~15 kHz | >40% around 15 kHz |
| UINTR | kernel-level when target dormant | catastrophic in the mixed case |
| SOFTWARE | moderate | not acceptable at 100 kHz |
| DULI V1/V2 | near 300 kHz | <5% at 100 kHz |
| DULI V5 | >250 kHz | 8% above 250 kHz |
At the common 10 kHz operating point, all DULI variants stay below 0.5% jitter — about 60× better than kernel-mediated handling. The 20 kHz floor required by industrial drives is met with a wide margin, while an unrelated process keeps interleaving.
Real-time + best-effort on one core
A Modbus-RTU foreground (one interrupt per byte) runs next to an image recognition background. This is the consolidation case: the real-time task wants low worst-case latency, the background wants throughput.
| Scheme | At 115.2 kbps | At 1 Mbps | Max baud |
|---|---|---|---|
| KERNEL | 143 → 92 FPS (−36%) | fails | <300 kbps |
| UINTR | same as KERNEL (target dormant) | fails | <300 kbps |
| SOFTWARE | mild loss | 68 FPS (−52%) | >1 Mbps |
| DULI V1 | ≤5 FPS loss | 108 FPS (−24%) | 2 Mbps |
| DULI V5 | ≤5 FPS loss | 120 FPS (−17%) | 2 Mbps |
At the ubiquitous 115.2 kbps, DULI's throughput penalty is roughly 10× smaller than kernel forwarding and 2× smaller than the best software path. At 1 Mbps, the kernel baselines are already out of the picture.
Area and integration effort
The extension's core-area overhead ranges from +23% (V1) to +66% (V5), but the core is a small fraction of a real die: on the four decapped SoCs the extra area is 0.03%–0.91% of the total die. See the design-space page for the table.
Integrating DULI into an existing microkernel required:
| Variant | Added source lines | Share of kernel + HAL |
|---|---|---|
| V1 / V2 | +216 | +2.14% |
| V5 | +270 | +2.67% |
On a 5 856 + 4 249 SLoC kernel and HAL, that is a small, reviewable change — no interrupt-path code, only registration, budget replenishment and the new user-level return instruction.
What the numbers do not cover
- Single core. Global interrupt routing and arbitration are future work.
- No cache in the prototype. The extension is minimally affected because its tables can live in TCM; the kernel path would suffer more.
- No FPU context. FPU registers are out of scope; the baseline FPU is present for area accounting only.
- Average case is not the point. Every result above is about the worst case. Tail-chaining and other average-case optimizations are deliberately left out.