Mamadou Wane

TVC · Linux timing and control simulation

Measured closed-loop control at 500 Hz

A C++20 controller and Python simulator for one-axis thrust-vector control, with deterministic acceptance tests and measured timing on bare-metal Linux.

Artifacts: View sourceRead the results

Measured on Linux · September 15, 2026

18.0 µs Wakeup jitter, p99.9 Median of eight closed-loop runs. Figure 3

401 to 433 µs Served sensor-to-actuator latency, p99.9 Range across eight closed-loop runs. Figure 4

Deterministic simulation

400/400 Deterministic acceptance cases passed 200 seeds at each of two actuator delays. Figure 11

Release
v0.2b · 3d3854c6
Campaign
September 15, 2026
Stack
C++20 controller · Python simulator · UDP · Linux

Abstract

TVC pairs a C++20 controller with a Python simulator for one-axis thrust-vector control over UDP. A Linux timing investigation traced delayed wakeups to timer placement on another CPU. Disabling timer migration reduced p99.9 wakeup jitter from 380 µs to 16.6 µs in 15,000-cycle diagnostic runs (Figure 6). Here p99.9 is the value that 999 of every 1,000 samples in a run stayed at or below; it is not the run’s maximum.

A separate closed-loop campaign on September 15, 2026 recorded median per-run p99.9 wakeup jitter of 18.0 µs across eight 300,000-cycle runs. Per-run p99.9 served sensor-to-actuator latency ranged from 401 to 433 µs. Served latency includes only cycles using fresh sensor data.

Separately, in deterministic lockstep simulation, all 400 predeclared synthetic acceptance cases passed, and a complete rebuild and rerun reproduced all 1,600 artifact files byte for byte. The results establish behavior on the tested simulation and machine configuration, not a hard real-time guarantee or validation on a physical vehicle.

Recorded run. S5-overgust, ticks 900 to 1,700. Simulation output, separate from the Linux timing measurements · recorded lockstep run, seed 1, actuator delay D=0. θ is the simulator’s pitch angle, δ the controller’s commanded nozzle angle; both in radians on a linear axis, against ticks of 2 ms. The shaded window is the declared gust, applied as 4.05 N·m from tick 1000 to 1099. Figure 9 and its events table give the exact values.

1System design

TVC simulates how a vehicle controls its pitch by changing the direction of thrust. I built it to understand how control software behaves when communication and scheduling affect the inputs it receives.

TVC uses two closed-loop modes. Lockstep checks behavior in simulated time. Free-run measures execution on independent schedules. A separate timing harness provides the comparison workload.1

00

Simulation output · recorded lockstep runs S5-overgust and S6-blackout, seed 1, actuator delay D=0

S5-overgust · tick 1173 · θ +0.1514 rad · δ +0.1200 rad (clamp) · fresh

Parts of the drawing
Process A
the Python simulator: plant, sensor and actuator FIFO
Plant
the one-axis vehicle: pitch θ about the pivot; 60 N of thrust through a nozzle 0.45 m below it, deflected by δ
Test stand
holds the vehicle on one pivot axis
Sensor
the simulator observes θ and ω each tick; beyond ±0.30 rad on the scale the episode ends as diverged
Disturbance
the scenario declares a 0.45 rad gust angle; the simulator applies 4.05 N·m on ticks 1000 to 1099 of S5
Simulator port
sends S[k] each tick; in lockstep it resends S[k] until A[k] arrives
Actuator FIFO
holds each command for the configured delay: one tick in nominal free-run, zero in these recorded runs
S[k]
sensor frame, a 58-byte UDP datagram with the tick, θ, ω, flags and a CRC-32C
A[k]
actuator command, a 62-byte UDP datagram with δ, the controller's status and its staleness
Process B
the C++20 controller: admission, episode policy and PID
Admission
classifies each arriving frame; the cradle keeps the last fresh sample
Controller console
one process; in lockstep one cycle per new S[k], and a resent S[k] gets the cached A[k]; free-run schedules cycles at 500 Hz
Staleness
controller cycles since the last fresh sample
Episode policy
staleness 0: PID runs once · 1 to 8: hold the last δ · 9 to 20: neutral, δ = 0 · 21: SENSOR_LOST
P
Kp·θ, Kp = 3.277; dial ±0.5 rad
I
integrator state, Ki = 7.68, clamped to ±0.12 and held while δ saturates toward the error; dial ±0.5 rad
D
Kd times the filtered pitch rate, Kd = 0.309, filter weight 1/3; dial ±0.5 rad
δ
the command: P + I + D clamped to ±0.12 rad when the PID runs, otherwise the last δ or 0
Episode state
init, armed, flying, terminated
Dispatch
sends A[k] back to the simulator
Control record
128 bytes per cycle into a 4,096-slot ring that a separate thread drains; the ring's fill and motion here are schematic
Figure 1. Two processes and two packets.

Schematic of the closed loop, drawn from simulation output: the recorded lockstep runs S5-overgust and S6-blackout (seed 1, actuator delay D=0), replayed when the page's script runs and otherwise held at S5-overgust tick 1173. The Python simulator, on the left, owns the plant, the sensor and the actuator FIFO; its stand draws the one-axis model it integrates. The C++20 controller, on the right, owns admission, the episode policy and PID. Each tube is a UDP link and each canister one datagram: sensor frames S[k] go up in blue and actuator commands A[k] come back solid. Orange marks a frame with no sample and the SENSOR_LOST end of an episode. Tick, θ, ω, δ and staleness are the run's recorded values at that tick and the dials settle on them; the gust torque comes from the scenario. Lockstep runs carry no wall-clock timing (a tick is 2 ms of simulated time), so only the order of events inside a tick is drawn. The record ring's fill and motion are schematic, and the timing harness is not drawn.

SourcesOperating modes · Transaction handling · Episode policy · Plant model · Control constants · Actuator FIFO · Lockstep simulator · Control record and ring · Gust and blackout · ka · Scenario S5-overgust · Scenario S6-blackout · Golden CSVs, extracted at a3a2d105

Each sensor frame carries the pitch angle θ and pitch rate ω for one tick. Each actuator command carries the requested nozzle angle δ, computed by PID control: a proportional, an integral and a derivative term on the pitch error. The controller writes one control record per cycle into a bounded ring that a separate drain thread empties, so recording never sits on the control path.

1.1Two ways to advance the loop

Lockstep. The simulator and controller finish one sensor-and-command exchange before the next simulation step. Each completed transaction advances simulated time by 2 ms. Retries resend cached responses without another controller update.

Free-run. The simulator and controller follow independent 500 Hz schedules. Each controller deadline starts a scheduled cycle. Packet arrival supplies observations; it does not create an extra controller update.

(a) Locksteptransaction order · 2 ms of simulated time per tick

tick 0 · 0 msobserve · send S[0]
S[0]
A[0]
cycle 0fresh S[0] · PID once
tick 1 · 2 mspush A[0] · pop nonestep 0 · neutralobserve · send S[1]
S[1]
A[1]
cycle 1fresh S[1] · PID once
tick 2 · 4 mspush A[1] · pop A[0]step 1 applies A[0]observe · send S[2]
S[2]
A[2] lost
cycle 2fresh S[2] · PID once
no reply in timeresend S[2]
S[2] again
A[2]
duplicate S[2]cached A[2] · no PID
tick 3 · 6 mspush A[2] · pop A[1]step 2 applies A[1]observe · send S[3]
S[3]
A[3]
cycle 3fresh S[3] · PID once
tick 4 · 8 mspush A[3] · pop A[2]step 3 applies A[2]

(b) Free-runwall clock · one period is 2 ms

0–2 ms
prologue S[0]sim clock starts
S[0]
0–2 ms
A[0]
cycle 0arrival + 400 µsfresh S[0] · PID once
2–4 ms
body 0 · step 0push A[0] · pop nonenozzle neutral
S[1]
2–4 ms
A[1]
cycle 1fresh S[1] · PID once
4–6 ms
body 1 · step 1push A[1] · pop A[0]applies A[0]
S[2]
4–6 ms
A[2]
cycle 2fresh S[2] · PID once
6–8 ms
body 2 · step 2push A[2] · pop A[1]applies A[1]
S[3], late
6–8 ms
A[3], held
cycle 3no fresh frame yetholds A[2] · no PID
8–10 ms
body 3 · step 3push A[3] · pop A[2]applies A[2]
S[4]
8–10 ms
A[4]
cycle 4S[3] supersededfresh S[4] · PID once
Figure 2. Two ways to advance the loop. Nominal free-run configuration: 400 µs phase offset and one tick of actuator delay. The phase offset is the delay the controller adds between the arrival of the first frame and its first cycle, so that each later frame has time to arrive before the cycle that consumes it. The lockstep sequence uses the same one-tick delay so the two can be compared directly. Both sequences show event order only: rows are not drawn to time scale, and the measured latencies are in §3. The recorded runs further down use no actuator delay and say so.SourcesLockstep simulator · Transaction handling · Free-run simulator · Scheduled controller · Phase-alignment decision

1.2Missing input

When fresh input stops arriving, the controller holds its previous command, then requests a neutral nozzle angle. Continued staleness ends the episode.

Table 1. Missing-input policy. The policy follows the controller’s staleness count: fresh, hold (staleness 1 to 8), neutral (9 to 20), SENSOR_LOST at 21.SourceMissing-input policy

staleness 0

Fresh. PID runs once.

staleness 1 to 8

Hold. The controller holds its previous command.

staleness 9 to 20

Neutral. δ = 0.

staleness 21

SENSOR_LOST. The episode ends.

Notes

  1. The timing harness runs the same control cycle against an in-process stand-in plant; it is the workload behind levels L5 (telemetry disabled) and L7 (control recording) in the measurements below.

2Method

On September 15, 2026, I ran eight interleaved repeats of three configurations on the qualified machine, meaning the documented hardware and software configuration that was tested (§2.2). Each run recorded 300,000 cycles after 5,000 warmup cycles at 500 Hz. All 24 runs completed with no missed deadlines, reruns or replacements.[3]

The configurations are levels on the project’s measurement ladder, L0 to L8, where each level adds one change to the one before. Table 2 describes the three used here.

Table 2. Campaign configurations. Order: L5.r1, L7.r1, L8.r1 through L8.r8.
LevelConfigurationRole in the campaign
L5timing harness with telemetry disabledgated against the August 29 reference and its limit
L7timing harness with control recordingpaired with L8 in every repeat
L8free-run closed loop with control recordingthe closed loop, gated on latency, coverage and integrity

2.1Definitions

Wakeup jitter
Wakeup jitter is how late the control thread resumed after its deadline.[6]
Served latency
Served latency runs from the simulator’s sensor-frame timestamp to the controller’s local completion of the actuator-command send. Cycles that reuse a held command remain in the coverage denominator and are excluded from the served-latency distribution. Simulator receipt and actuator application are separate events.
Served coverage
Served coverage is the served count over the 300,000 recorded cycles; coast cycles held the previous command because no fresh frame had arrived, and count toward coverage only.

2.2Platform

Vehicle on CPU 7 under SCHED_FIFO 80 with locked memory and absolute deadlines; the L8 simulator peer pinned to CPU 11 under SCHED_OTHER, running scenario S1-hold at zero loss with the one-tick actuator FIFO and the 400 µs phase offset. Idle states were disabled on CPUs 6, 7 and 11 for the whole session; timer migration off; performance governor; kernel 7.0.0-30-generic on an HP ProBook 465 G11 (Ryzen 7 7735U).[7]2

2.3Acceptance criteria

Declared budgets: p99.9 budget 1,000 µs, maximum-latency budget 2,000 µs, served coverage at or above 99%.

Table 3. Acceptance criteria and outcomes September 15 timing campaign. The 400 deterministic acceptance cases are separate lockstep evidence, in §6.
CriterionThresholdObservedOutcome
L5 gate: median p99.9 wakeup jitter≤ 24.8 µs19.1 µsmet
Served latency p99.9, every L8 run≤ 1,000 µslargest 432.9 µsmet
Maximum served latency, every L8 run≤ 2,000 µslargest 484.9 µsmet
Served coverage, every L8 run≥ 99%lowest 99.990%met
Integrity checks, every L8 rundeclaredpassedmet
Median paired difference, L8 minus L7≤ +2.0 µs−0.32 µsmet

Notes

  1. The campaign was measured from source identity 0294935f, built from commit 7e7b70e9; the release commit 3d3854c6 publishes the evidence.

3Timing results

3.1Wakeup jitter

The L5 median was 19.1 µs against a 16.5 µs historical reference and a 24.8 µs acceptance limit.3

Figure 3. Wakeup jitter, eight runs per configuration. Measured campaign · September 15, 2026 · each mark is one run’s p99.9 wakeup jitter. Linear axis, µs. ○ one run’s p99.9 · │ median of the eight run values · dashed: the L5 gate’s reference and limit.SourcesL5 gate · Campaign record

3.2Sensor-to-actuator response

Across the eight closed-loop runs, served latency p99.9 ranged from 401.4 to 432.9 µs. The largest observed served latency was 484.9 µs. Every run passed the declared latency, coverage and integrity checks.4

(a) Against the declared budgets

(b) Per run

Figure 4. Served latency, eight L8 runs. Measured campaign · L8 free-run closed loop · 300,000 recorded cycles per run. Linear axes, µs. ○ served latency p50 · ● served latency p99.9 · │ maximum served latency · right column: served coverage and coast cycles. The 400 µs line is the phase offset setting, the time the controller waits after a frame’s scheduled send before its cycle; the marks are the measured values. Minimum served coverage observed: 99.990%.SourcesLatency analysis output · L8 gate

3.3The timing cost of closing the loop

Each repeat paired the control-recording harness with the free-run closed loop. All eight L8 minus L7 differences in p99.9 wakeup jitter were negative. The median paired difference was −0.32 µs, within the predeclared +2.0 µs acceptance margin.5

Each pair compares run-level percentiles. Cycle samples were not pooled across runs.

Figure 5. Paired change in p99.9 wakeup jitter. L8 minus L7 · eight interleaved repeats · each row is one repeat, run back to back. Linear axis, µs. ● the repeat’s difference · dashed: the median paired difference and the acceptance margin.SourcesPaired comparison output · Platform configuration

The comparison is scoped to this campaign: the closed loop’s wakeup tail did not exceed the harness’s on the same machine and afternoon. It says nothing general about networking or feedback making software faster, and no cause is assigned to the consistent negative direction.

Notes

  1. The reference session disabled idle states on two CPUs; this session used three.
  2. One run, L8.r4, sits about 22 µs above the other seven at p50 and 25 µs at p99.9 with its own wake and compute figures unchanged, consistent with a peer-side shift; no cause is assigned.
  3. The sign test on the eight paired differences (8 negative, 0 positive, two-sided p = 0.0078) is supplemental and decides nothing; the median difference is the rule.

4The timing investigation

4.1Why pinning the thread did not pin its wakeup timer

Pinning the control thread did not always keep its wakeup timer on the same CPU. The loop sleeps with clock_nanosleep, which arms an unpinned kernel timer, and with timer migration enabled the kernel could move that timer to another CPU: six samples of /proc/timer_list found it on CPU 4 twice and on CPU 7 once. A wakeup delivered from another CPU then waited on that CPU’s exit from idle.

In a 15,000-cycle diagnostic pair, disabling timer migration reduced p99.9 wakeup jitter from 380.415 to 16.591 µs.

Figure 6. Timer diagnostic pair. Measured diagnostic pair · 15,000 cycles per run. Linear axis, µs. Maxima: 893.951 and 27.151 µs. Both diagnostic runs covered 15,000 cycles at L5 with idle states disabled on CPUs 6 and 7. Only the timer-migration setting changed. These short comparisons preceded the campaign below.SourcesDiagnostic manifest · Investigation and interpretation

4.2Historical timing-harness campaign

The subsequent August campaign measured a 16.5 µs median p99.9 at L5 across three ten-minute runs. Those results describe the earlier timing harness and its stand-in workload.6

Figure 7. Historical timing-harness campaign. August 29, 2026. Three runs per level, 300,000 measured cycles per run. ○ individual run p99.9 · │ median of the three run p99.9 values. The axis is logarithmic, with equal spacing for each tenfold increase from 1 to 1,000 µs. L3 to L4 is the pinning step, marked on the chart. L0 used relative sleeps: its median p99.9 lateness was 14.9 seconds, beyond this axis. Each point shows one run’s 99.9th percentile; the range spans the three repeats and shows their spread, with no confidence interval implied. This campaign measured the stand-in workload with the pinned-timer discipline; the September closed-loop campaign above is separate evidence.SourcesCampaign results · Definitions and method · Measurement code at 0fafb7c

4.3Aligning the simulator and controller

The first free-run calibration exposed a scheduling mismatch: the measured response included an extra simulation period. I shifted the simulator’s schedule and kept the intended one-tick control delay in the actuator FIFO.[8]

A second calibration showed that simulator scheduling still limited coverage. The final configuration placed the simulator on a declared housekeeping CPU with idle states disabled.

SourceSimulator peer CPU

4.4Selecting the phase offset

The final calibration compared 200, 400 and 800 µs offsets in three interleaved runs each. Every 200 µs run exceeded the 2,000 µs maximum-latency limit. Both 400 and 800 µs passed. The predeclared rule selected 400 µs as the smallest qualifying offset.[4]7

The selected configuration was then evaluated in the separate 24-run qualified campaign.

Figure 8. Phase-offset calibration. Calibration evidence · September 15, 2026 · three runs per offset · served latency against the two budgets that decide qualification. Linear axis, µs. ● served latency p99.9 · │ maximum served latency. Each row is one 300,000-cycle run. An offset qualifies only when every run keeps served coverage at or above 99%, p99.9 at or below 1,000 µs and maximum at or below 2,000 µs with clean reconciliation; the smallest qualifying offset wins. These nine runs fix one parameter and are not part of the release campaign.SourcesAnalyzer verdict · Calibration record · Calibration findings

Notes

  1. HP ProBook 465 G11, Ryzen 7 7735U, Ubuntu kernel 7.0.0-30-generic. Timer migration was disabled; idle states were disabled on CPUs 6 and 7. All nine pinned runs recorded no deadline misses; all three telemetry runs reported zero ring drops.
  2. The two earlier calibration attempts on September 14 stay retained on the measurement machine and are not committed, so they are not drawn here.

5Controller behavior

The recorded runs show two different responses: recovery from a gust that saturates the nozzle command, and termination after sensor input remains unavailable. Recorded lockstep runs: a gust response (S5-overgust) and a sensor blackout (S6-blackout), seed 1, actuator delay D=0. These are simulation outputs, separate from the Linux timing measurements.8

S5-overgust, events in the recorded golden run
Tickt, sEventθ, radδ, rad
10002.000Gust torque 4.05 N·m begins+0.0000+0.0000
10232.046δ saturates at +0.12 rad for 217 ticks+0.0092+0.1200
11002.200Gust torque ends+0.0937+0.1200
11732.346Peak pitch, 0.1514 rad (8.67°)+0.1514+0.1200
15743.148|θ| stays inside 0.005 rad from here−0.0050−0.0004
19993.998Excerpt ends; the run continues to tick 4999−0.0002+0.0000
Figure 9. S5-overgust. Tick axis, linear, ticks 900 to 1,700; one tick is 2 ms. S5 is the committed 2,000-tick excerpt of a 5,000-tick run that stabilized. The gust is the scenario’s declared 0.45 rad gust angle, which the simulator applies as the torque ka × 0.45 = 4.05 N·m from tick 1000 to 1099. θ is the simulator’s pitch angle in radians, δ the controller’s commanded nozzle angle in radians.SourcesScenario S5-overgust · Golden CSVs · Golden manifest · Control constants
S6-blackout, events in the recorded golden run
Tickt, sEventθ, radδ, rad
10002.000Uplink blackout begins; staleness 1, policy holds the last δ+0.0000+0.0000
10082.016Staleness 9, policy commands δ = 0 (neutral)+0.0000+0.0000
10202.040Staleness 21, episode ends SENSOR_LOST+0.0000+0.0000
Figure 10. S6-blackout. Each cell is one controller cycle after fresh input stops: hold (staleness 1 to 8, hatched), neutral (9 to 20), SENSOR_LOST at 21. S6 is the complete run.SourcesScenario S6-blackout · Missing-input policy

Notes

  1. The page’s copy of both runs was extracted at commit a3a2d105; the golden CSVs and scenario files are byte-identical at v0.2b.

6Deterministic acceptance

The S2-gust scenario starts from a 0.05 rad pitch angle while rotating at 0.5 rad/s and declares three gusts. Its campaign covered 200 seeds at each of two actuator delays, with 30% modeled loss in each direction over 10,000 ticks per case. All 400 cases passed the declared checks for termination, peak angle, settling, logical cadence and finite values.[5]

ScenarioS2-gust, three gusts

Seeds200 per delay

Modeled loss30% each direction

Length10,000 ticks per case

Deterministic acceptance cases passing each declared check, by actuator delay
Declared checkDelay 0Delay 1
Termination200/200200/200
Peak angle200/200200/200
Settling200/200200/200
Logical cadence200/200200/200
Finite values200/200200/200
All five checks200/200200/200

1,600/1,600retained artifact files reproduced by a complete rebuild and rerun

Byte for bytethe committed campaign manifest, reproduced by the final release run

400/400cases also passed by the Python reference

Figure 11. 400 deterministic acceptance cases. Delay 0: 200/200 · Delay 1: 200/200.Sources400-case manifest and artifact digests · Acceptance and comparison code

The final release run reproduced the committed campaign manifest byte for byte, and a complete rebuild and rerun reproduced all 1,600 retained artifact files. The Python reference also passed all 400 cases. Because it shares the plant model, that agreement checks implementation behavior without independently validating the physics.

Controlled stalls and packet bursts test bounded receive work, cycle accounting, future-frame storage and shutdown. Recording audits reconcile the reported measurements with the events that produced them. The separate bare-metal campaign establishes the timing results shown above.

SourcesScheduling diagnostics · Runtime and terminal tests · Recording audit

7Limitations

What the evidence covers

  • The timing results cover the documented Linux configuration and the zero-loss S1-hold workload, which holds attitude from a 0.02 rad starting pitch angle with no gusts.
  • The physical model covers one rotational axis with ideal sensors and an idealized actuator.
  • The deterministic acceptance results cover the declared synthetic loss matrix.

Not established

  • A hard real-time bound has not been established.
  • TVC has not been flight-tested.
  • Long-duration free-run operation under loss remains unmeasured.

8Artifacts

Release v0.2b includes the implementation, acceptance manifests, compact measurement baselines and methodology.

  1. 1Source at v0.2bCommit 3d3854c6, the publication of the released evidence.
  2. 2Release notesWhat changed and the evidence boundary.
  3. 3Qualified campaign24 runs, per-run summaries, gate outputs and the hash inventory of the raw recordings.
  4. 4Phase calibrationNine runs and the predeclared selection rule.
  5. 5Deterministic acceptanceThe 400-case manifest with artifact digests.
  6. 6Measurement methodologyWhat wakeup jitter and served latency mean and how the campaign was run.
  7. 7Platform configurationThe machine, kernel, isolation and discipline every number comes from.
  8. 8Phase-alignment decisionWhere the one-tick control delay lives in free-run, and why.

The repository contains compact evidence and artifact inventories. Full raw recordings are retained separately. This page uses the recorded results; no campaign was rerun for the website. Historical measurements stay pinned to commits that carry them unchanged: measurement code 0fafb7c, publication 851d61c.

APer-run values

Table A1. Wakeup jitter p99.9 per run, µs · eight interleaved repeats Each value links to the run summary it comes from.
RepeatL5L7L8L8 minus L7
r119.58318.15917.983−0.176
r219.56718.20717.823−0.384
r319.23118.43117.807−0.624
r419.00718.33518.079−0.256
r518.75118.12718.079−0.048
r619.11918.28717.887−0.400
r719.08718.28718.127−0.160
r819.08718.55917.935−0.624
Median19.118.318.0−0.32
Table A2. Served sensor-to-actuator latency per L8 run, µs · 300,000 recorded cycles each Coverage is the served count over the recorded cycles; coast cycles held the previous command.
Runp50p99.9MaximumCoverageCoast
L8.r1396.543407.551455.6790.999979
L8.r2401.151409.087452.3510.9999613
L8.r3401.919410.367452.6070.9999516
L8.r4419.327432.895475.1350.9999127
L8.r5396.543403.967455.4230.9999030
L8.r6394.751401.407484.8630.9999322
L8.r7400.639408.063473.5990.9999223
L8.r8397.567404.223465.6630.9999417
Table A3. Historical timing-harness campaign, August 29, 2026 · three runs per level, 300,000 measured cycles per run Exact values in µs link to the corresponding run summaries.
LevelAdds to the previous levelR1R2R3Median
L1Absolute deadlines402.175331.263323.071331.3
L2Lock and prefault memory93.695407.551408.063407.6
L3FIFO priority 808.575400.639430.847400.6
L4Pin thread to CPU 715.99116.49516.36716.4
L5Remove allocating log16.35116.54316.83116.5
L6Enable telemetry17.61517.26316.65517.3
Table A4. Measured diagnostic pair · 15,000 cycles per run
Timer migrationp99.9 jitterMaximum
Enabled380.415 µs893.951 µs
Disabled16.591 µs27.151 µs
Table A5. Phase-offset calibration, served latency per run, µs · 300,000 recorded cycles each Each run links to its summary. An offset qualifies only when every run passes.
Runp50p99.9MaximumCoverageCoastVerdict
200 µs, r1201.215207.7432146.30.99965104fails: maximum above 2,000 µs
200 µs, r2199.423206.3352103.30.9998060fails: maximum above 2,000 µs
200 µs, r3198.399207.3592132.00.9998254fails: maximum above 2,000 µs
400 µs, r1496.383503.551549.90.999978passes
400 µs, r2394.751403.199454.90.9999514passes
400 µs, r3399.615407.039446.50.999979passes
800 µs, r1803.327811.519872.40.9999611passes
800 µs, r2801.279811.519845.80.999979passes
800 µs, r3798.719808.447870.90.9999611passes