Skip to content

← All documentation

Post-install setup · Y2Reborn

Reborn Platform 1.0 performance and responsiveness

Documentation published by SchulzCode/Y2Reborn.

Instructions published by the project, shown here word for word.

Reborn Platform 1.0 performance and responsiveness

2026-10-04. Source and validation are isolated on codex/platform-v1-reborn-performance. Product UI v2 is preserved. No flash, push, production package change or main-worktree edit is performed by this pass.

The measured bottlenecks are fixed: wired partial-write churn, repeated kernel-log reads, periodic hardware observation on the UI thread, per-quad GL submission, redundant radio redraws and frame-budget drift. Playing CPU falls from 87.95% to 11.21% of one core. The four-cover cache also keeps valid entries when another cover is corrupt or missing.

Evidence and baseline

Installed platform: Y2LINUX-BASELINE-02, Linux 8584ccd85f052f351fe51650b2348c83ca894ed4, installed Reborn b71b468860233faa0a42b8448ec5777fa952b8e3, kernel 6.18.0-y2linux-baseline-02, root 2025.02.18-platform-v1.21. The real panel is 480x360; Mali400, GLES2 Mesa 24.0.9, EGL 1.4.

The device rebooted during an independent suspend qualification before the final matched comparison. Both final executables are therefore rerun on boot88b85fa3; earlier boot27e6d684 receipts remain historical. This pass performs no suspend trial.

Baseline executable: installed Reborn source b71b4688 plus opt-in profiling/benchmark instrumentation, with original rendering and loop behavior. Candidate source: 069415a4207c00f0a32a3a2ac00602ddea29a895. Exact ARM executable and benchmark SHA-256 values are retained in summary.json; raw binaries, traces, captures and build logs remain in ignored out/performance/.

Before boot 88b85fa3-2282-4d93-b0b8-818a105ddd0a; after boot 88b85fa3-2282-4d93-b0b8-818a105ddd0a. Each run restores the installed service and original data and ends on its starting boot with taint 0. Physical operations hold /tmp/y2-platform-v1-device.lock. Temporary executables use a private bind-mounted copy of app data; SQL uses fresh private scratch.

The live input fixture uses the original three-track library and one private 40-second PCM queue entry. The separate product benchmark uses 10,000 tracks, 50 artists and 1,000 ordinary albums, plus stress collections containing all 10,000 tracks. Live input latency is not represented as a 10k-library end-to-end measurement.

Controls use synthetic records through the real supported evdev handles and actual kernel monotonic timestamps. They exclude mechanical, GPIO/wheel IRQ and debounce timing. Select/Back timestamps belong to routed release events; driver-generated releases can precede the fixture release write, so the analyzer joins the nearest fixture record and checks the routed action. KMS completion is not light reaching the panel. Handler-complete timing includes effects/I/O and is an upper bound on AppState mutation. No analog audible-response timing is claimed.

One matched run per executable, 32 frames per screen, 16 collection navigation repetitions, 17 Now Playing entries, 1,000 fast wheel steps and four process starts are retained. Small-sample p95 values are descriptive rather than confidence bounds. Production governor/guards remain in use; no benchmark CPU-frequency or radio override is applied.

Exploratory receipts with per-event evdev reopen overhead or an unavailable/rejected restored queue are excluded from control/playback acceptance. The final persistent-handle fixture verifies successful playback and zero dropped trace samples.

Input and navigation

All values below are milliseconds, p95. AppState -> frame completion is retained separately in the JSON. Single-sample routes are marked by their count.

ActionSamples before/afterEvent -> handler before/afterEvent -> KMS before/after
Ordinary wheel55/5514.87 / 0.3659.93 / 17.52
Fast 1000-wheel sequence1000/100029.06 / 10.6027.99 / 26.35
Home -> Library1/110.45 / 0.3422.80 / 12.98
Library -> Albums16/1612.53 / 0.2331.48 / 17.24
Albums -> Album16/1615.33 / 0.2634.21 / 17.09
Album -> Albums16/1614.65 / 0.3760.01 / 17.21
Albums -> Library16/1621.24 / 0.2667.57 / 17.18
Library -> Artists16/1646.01 / 0.3260.95 / 23.45
Artists -> Artist16/1626.63 / 0.2733.18 / 18.05
Artist -> Artists16/1615.22 / 0.2553.81 / 25.63
Artists -> Library16/1615.76 / 0.3262.07 / 16.62
Library -> Tracks1/112.52 / 0.2129.58 / 4.17
Home -> Now Playing17/1731.44 / 0.3077.61 / 17.15
Now Playing -> Home17/1715.26 / 0.2565.54 / 18.15
Home -> Queue1/110.16 / 0.2428.65 / 12.56
Queue -> Home1/17.38 / 0.1723.40 / 3.57
Home -> Settings1/110.40 / 0.2328.56 / 17.96
Play/Pause2/217.50 / 19.6921.75 / 42.47
Volume up while playing16/1625.27 / 15.1150.28 / 33.13
Volume down while playing16/1626.73 / 10.9451.76 / 24.91
Screen wake1/142.44 / 39.2757.31 / 53.84

The two Play/Pause events above are insufficient to establish a regression. A separate matched replay on the same boot varies frame phase, waits for native playback, and records 16 resume and 16 pause events per executable. Both executables use the same private queue and original Now Playing screen; SQL/GPU/idle fixtures are skipped. The supplemental receipt retains all samples and zero trace drops/XRUNs/playback errors.

Repeated controlSamples per sideHandler p95 before/afterKMS p95 before/after
Resume1624.68 / 15.6343.98 / 22.55
Pause1639.84 / 17.2264.70 / 38.50

The fast sequence routes all 1,000 single steps in both runs, with zero selection mismatches or non-single steps. Direction alternates to exercise one-detent semantics without triggering intentional acceleration; acceleration/duplicate suppression code is unchanged and its existing tests pass. 801 / 641 steps are superseded before an individual frame. KMS latency for that sequence describes only unsuperseded frames and must not hide the handler tail; all-action p99/max values remain in the JSON.

Volume updates reach the live sink gain control before handler completion; persistence remains synchronous and measured. Playback state and ALSA parameters are retained in the final receipt. Audible timing, peer Bluetooth audio and physical long-press ergonomics require separate observation.

Frame and rendering cost

32 complete frames per screen on real KMS. Values are p95 ms. Submission ends before swap/KMS waiting; CPU is thread CPU time across submission and presentation.

ScreenLayout before/afterGL submit before/afterRender CPU before/afterPresent before/after
home0.19 / 0.207.97 / 1.269.77 / 1.8412.32 / 14.62
music0.13 / 0.154.06 / 1.205.22 / 1.8213.19 / 14.38
artists0.12 / 0.155.12 / 1.136.57 / 1.6512.15 / 14.54
albums0.18 / 0.287.49 / 1.209.94 / 1.7612.02 / 14.66
tracks0.19 / 0.256.14 / 1.337.58 / 1.9611.78 / 14.49
artist0.25 / 0.227.05 / 1.956.91 / 2.6812.08 / 13.86
album0.22 / 0.216.42 / 1.608.20 / 2.2412.22 / 14.22
now_playing0.12 / 0.183.89 / 2.075.09 / 2.8211.90 / 13.92
queue0.23 / 0.267.73 / 1.399.85 / 2.0711.53 / 14.42
settings0.21 / 0.244.88 / 1.236.36 / 1.8612.43 / 14.41

Present waiting can increase when CPU submission finishes earlier. The change reduces CPU work; it does not claim a faster panel refresh or bypass vblank. The live complete-frame p50 is 15.97 -> 11.12 ms, p95 18.79 -> 17.26 ms.

Home keeps all 147 quads and reduces draw calls from 147 to 9. Batching preserves adjacent texture order and uses exactly 49,152 bytes of fixed staging storage.

Cold catalog cost is retained separately from warm layout. First Albums layout is 26.66 -> 29.80 ms; first Tracks 15.77 -> 20.61 ms. Catalog algorithms are unchanged; these single cold samples are not optimization claims.

Stress destinationTracksSelect -> complete layout p95Render CPU p95
artist100007.091.51
album1000034.362.79

Both stress fixtures verify Select and Back. They measure UI/renderer work on the device, not evdev-to-photon latency. No before/after claim is made for these newly added stress cases.

The single-album 10k-track extreme still spends 34.36 ms in Select plus complete layout. This pass retains that measured limit rather than introducing an unmeasured collection-cache rewrite; normal 10k-library album fixtures contain ten tracks per album.

Ten complete RGBA screen captures differ in 600 of 6912000 channels (0.0087%). Maximum difference is 5/255; 47 channels differ by more than one step. The changed pixels are small antialiased edges; this is bounded near-equivalence rather than bit-identical rendering. Layout, assets, text, colors and draw order are preserved. These captures use the benchmark UI without live cover content. Capture/readback is qualification-only and outside timed frame samples; normal rendering uses neither readback nor glFinish.

Artwork and allocations

JPEG/PNG/WebP and the fourth cover each decode to 160x160 RGBA (102,400 bytes). Four valid entries bound cache payload to 409,600 bytes, plus transient reply/decoder storage. GPU textures keep their existing lifetime. The sequence deliberately changes covers and uploads each changed route; unchanged selections are suppressed and cannot repeatedly decode/upload on static frames.

Artwork measureBeforeAfter
First four decodes, range ms6.64–30.056.09–9.25
JPEG after corrupt/missing requests6.24 ms; cache miss0.10 ms; cache hit
Maximum upload ms0.680.64

Malformed and missing covers return no pixels and cause no upload. The final fixture asserts all eight expected warm hits, preservation of the four valid entries after failed covers, and suppression of all 14 unchanged route repeats.

Calling-thread Rust allocation windowMean callsMean allocated bytes
1000_scrolled_frame_layouts65.0858903.26
1000_wheel_actions4.0074.00

Per-screen cold and warm layout counts remain in the JSON. Counts include allocations/reallocations on the calling Rust thread, exclude C/GL allocations and describe cumulative bytes rather than retained heap. Only reborn-bench installs the counting allocator. Normal Reborn retains its existing allocator. Warm layout cost is small enough that draw-list/glyph/string pooling is rejected; eliminating needless idle frames is more useful.

Startup

Elapsed from Rust run entry unless marked external exec. Four warm application starts per executable; nearest-rank p50/p95 are ms. These are not new cold-boot trials.

BoundaryBefore p50 / p95After p50 / p95
graphics_ready134.00 / 138.00132.00 / 134.00
storage_ready146.00 / 150.00144.00 / 146.00
database_ready152.00 / 156.00150.00 / 151.00
library_workers_ready152.00 / 156.00150.00 / 152.00
core_services_ready160.00 / 164.00158.00 / 159.00
audio_ready160.00 / 165.00158.00 / 160.00
radio_workers_ready161.00 / 166.00159.00 / 161.00
runtime_ready166.00 / 172.00164.00 / 165.00
ready189.00 / 210.00176.00 / 185.00
library_ready247.00 / 255.00271.00 / 303.00
interactive759.00 / 779.00493.00 / 499.00
exec_to_first_KMS_completion213.14 / 228.74197.43 / 210.28

The previously retained Baseline02 boot27e6d684 log reports first application frame at 446 ms from run entry and application-ready at 41.343 s after kernel boot. That observation is preserved separately; no improved cold-boot claim is made. The boot cover uses the same Product v2 frame count and handoff. Correcting start-to-start frame pacing removes the accidental extra delay before first interactivity.

Platform/radio workers start asynchronously. Selected screens do not require an initial platform-client snapshot; the first successful snapshot now logs platform_ready when actually requested. No startup connection-time comparison is invented, and the UI does not wait for that lazy API operation.

CPU, idle and blocking I/O

CPU percentages are of one core; context switches include scheduling/I/O and are not exact timer wake counts. Paused states use 10-second windows; playing uses five seconds. The optional one-second audio syscall profile runs afterward, outside these measurements.

StateFrames before/afterCPU % before/afterSwitches/s before/after
home_static_paused14.0 / 0.04.96 / 1.88133.44 / 47.23
now_playing_paused14.0 / 0.05.35 / 2.67133.65 / 48.90
playing12.0 / 5.087.95 / 11.21350.42 / 296.50
settings_menu_idle14.0 / 0.05.76 / 2.47133.86 / 48.11
screen_off_paused0.0 / 0.04.25 / 2.8789.27 / 49.11

C1 entries progress in these windows; C2/C3 counts are zero under the existing connected-USB/radio guards. Qualified CPU0 C3 policy remains Enabled, budget -1, disable 0 in the restoration receipt. This pass reduces application wakeups without modifying those guards or claiming electrical battery savings/full suspend.

The repeated 2,048-record kernel-log pattern takes 95–105 ms in the retained on-device read reproduction, matching periodic input stalls. The watchdog now keeps a persistent nonblocking cursor and bounded 32-error history, reading new records rather than replaying the ring. Its filtering, truncation, overrun handling and retained history have a targeted test.

Power-supply reads take 10–20 ms; native filesystem safeprobes about 5 ms per volume. Read reproductions, block probe timings, and kernel-read timings support those boundaries. Periodic reads now use the existing watchdog and one bounded request/result slot; the UI applies replies, discards stale music-directory media results, and retains source-change/scanner/playback ownership. Shutdown-intent polling and prepare/ack paths remain on their existing control path.

The actual background observation sample p95 is 26.00 ms; this work is outside the UI event/render path. Normal worker-result service is bounded by the 50-ms main wait, while real input interrupts that wait immediately.

SQLite/library I/O already runs on its database/scanner workers. The matched baseline 10k page query p95 is 1.79 ms, artist 1.83 ms, album 1.08 ms; full library worker load is 189.86 ms. Database reopen/checkpoint timing is retained in the JSON. No schema, WAL, batching or query rewrite is introduced. The standalone uncached folder-enumeration fixture is heavier and lacks normal mounted source roots; it does not certify deep-folder navigation.

The original playing audio thread consumes 82.63% of one core; the final thread consumes 5.11%. The untimed pre-fix one-second profile records 5,959 ioctls and 4,469 clock reads. The write-size probes isolate the cause using the actual VolumeRamp source and normal S16/48k, 512-period, 4096-buffer wired sink: gain work allows a few new frames to become available, so repeated short writes never return EAGAIN and the loop keeps recomputing a 512-frame gain window. The probe sees over 10,600 writes/s, almost all below 64 frames, and approximately 999 ms CPU per second. A capacity wait reduces it to 131 writes and approximately 30 ms CPU; these are writer-probe results, distinct from the whole-application table above.

The final wired sink returns each accepted prefix immediately and waits on the next call, after control polling. It performs at most one configured 20-ms readiness wait per call, including ready->EAGAIN races; timeout/interruption consume no PCM, recovery and discard reset pacing, and fatal wait errors propagate. Bluetooth short-write pacing, formats, byte strides, buffers, gain/ramp and transport leases are preserved. The configured wait bound does not include unrelated scheduling time or pre-existing XRUN recovery.

Scripted fault coverage checks partial->timeout->EINTR->ready/EAGAIN->full plus wait XRUN/fatal propagation and unchanged Bluetooth positive-short behavior. Real ALSA-null tests check readiness, exact S16/S24/S32 frame counts, native recovery and discard; they do not simulate a physical hardware XRUN. Final real-device controls check resume, seek, wired, pause, resume, stop, resume, with active-playback SIGTERM exit in 317.28 ms. No hard kill is required. Exact metrics before the optional syscall observer and after controls are retained; deliberate native XRUN/peer Bluetooth/analog quality testing remains separate.

Implemented and rejected changes

Rejected: visual redesign; desktop frame assumptions; text/glyph/string pooling; larger cover cache; permanent screenshot synchronization; GPU/vblank/CPU-policy tuning; DB schema/query/persistence rewrites; speculative startup dependency removal. Targeted measurements favor these smaller changes. Large-queue persistence, analog audible latency, cold boot after installation, peer radios, full suspend and electrical power are separate remaining qualifications.

Validation, files and handoff

Local source commits are b8c05db (rendering/interactive loop) and 069415a4207c00f0a32a3a2ac00602ddea29a895 (wired pacing). The report/evidence and paired Linux closing audit are separate local commits; branch history records their final IDs. Linux admission is f3de513. Existing configured Luca author/committer and GitHub identity are preserved; no identity setting or model attribution is added.

Files changed in Reborn:

Y2Linux changes only its standing admission/closing gap audit and roadmap: docs/planning/roadmap-gap-audit.md and docs/planning/platform-v1-roadmap.md. Its source, memory map, packages, installed image and policy are unchanged by this pass.

Platform 1.0 verdict

PASS for the measured Product v2 application responsiveness and wired-playing CPU scenarios. Preserve the explicit limits above; this is a scoped application performance result rather than full-platform, analog/power/endurance or release acceptance. Existing epics remain open. The next boundary is integration of the independent platform branches, including source-epoch/prepare handling, followed by the relevant combined qualification; no deployment/push is authorized by this report.

During integration, preserve the storage owner's fresh FD/source admission when applying cached observations and invalidate inflight observations across source epochs/suspend prepare. Reconcile the local Bluetooth timeout change with its owner's event worker; that superseded hunk should give way to the event worker, with combined idle/control behavior remeasured. The independent full-resume failure remains a release gate.

Published by the SchulzCode/Y2Reborn project [1] [3]