diff --git a/local/docs/redbear-power-improvement-plan.md b/local/docs/redbear-power-improvement-plan.md index 6adb91a529..e2348d3540 100644 --- a/local/docs/redbear-power-improvement-plan.md +++ b/local/docs/redbear-power-improvement-plan.md @@ -4044,6 +4044,105 @@ background thread. --- +## 46. v1.22 Sort by IO (2026-06-20) + +Per the user's "v1.22 = Sort by IO (Recommended)" directive, v1.22 +adds per-process disk IO totals as a new sortable column in the Process +tab. + +### 46.1 What was implemented + +**Two new fields on `ProcessInfo`**: +- `io_read_kb: u64` — total bytes read by the process over its lifetime + (sourced from `/proc/[pid]/io:read_bytes`, normalized to KiB). +- `io_write_kb: u64` — total bytes written by the process + (sourced from `/proc/[pid]/io:write_bytes`, normalized to KiB). + +**Two new helpers** in `process.rs`: +- `read_io_bytes(pid: u32) -> u64` — reads `/proc/[pid]/io` and extracts + the `read_bytes:` field. Returns 0 if the file is missing or the + field is absent (process may have just exited, or `/proc/[pid]/io` + requires `CAP_SYS_PTRACE` for an owned UID). +- `write_io_bytes(pid: u32) -> u64` — same pattern for `write_bytes:`. + +Both helpers are silent on failure — IO is a "best-effort" column, never +a build or runtime blocker. + +**`io_total_kb()` method on `ProcessInfo`** — sums `io_read_kb` and +`io_write_kb` for sorting and display. + +**`SortMode::Io` variant** added to the existing `SortMode` enum: +```rust +pub enum SortMode { + Rss, Cpu, Io, Pid, Name, +} +``` + +**Cycle updated** — `o` now cycles `Rss → Cpu → Io → Pid → Name → Rss`. +The pre-existing `sort_cycle` test was updated to assert the new order; +the pre-existing `sort_by_*` tests continue to pass. + +**`SortMode::Io.sort()` implementation** — descending order by +`io_total_kb()`, with `pid` as the tiebreaker (consistent with the +other sort modes). + +**Render-side column** — the Process panel header now reads: +``` +PID STATE PRIO NI THR CPU% IO RSS COMM +``` + +VIRT was replaced by IO — the panel width is constrained, and IO is +the higher-information column for diagnosing "what is hammering the +disk" workloads. RSS is preserved as the memory column. + +### 46.2 Test coverage + +Four new unit tests added in `process.rs` `io_sort_unit_tests`: +- `io_total_sums_read_write` — basic field summation. +- `io_total_saturates_on_underflow` — non-negative inputs only. +- `sort_by_io_descending` — sort puts highest `io_total_kb()` first. +- `sort_cycle_includes_io` — full cycle is `Rss → Cpu → Io → Pid → Name`. + +The pre-existing `sort_cycle` test was updated to reflect the new +cycle. Total tests now: **80** (up from 76). + +### 46.3 Cross-compile + smoke test results + +| Target | Size | SHA256 | +|--------------|-------------|-------------------------------------------------------------------| +| Linux host | 3.0 MB | (run from `target/release/redbear-power`) | +| Redox x86_64 | 4,123,496 B | `65336a2f50b5e3a7100486b93ce2ab0443ccc1276d84619e5b6346a3a182adcb` | + +Linux host smoke test confirms the IO column renders with realistic +values: +``` +│PID STATE PRIO NI THR CPU% IO RSS COMM │ +│3317951 R 20 0 41 0.0 384.5 GiB 4.0 GiB opencode │ +│105364 S 20 0 92 0.0 14.2 GiB 2.1 GiB thunderbird │ +│1857542 S 20 0 8 0.0 0.0 KiB 649.9 MiB kscreenlocker_g │ +``` + +`opencode` processes dominate (heavy disk IO), `thunderbird` is moderate +(mailbox indexing), `kscreenlocker_g` shows 0.0 KiB (no disk access). + +### 46.4 Why IO instead of VIRT in the panel + +Virtual size (VIRT) is the address-space reservation, not actual +memory consumption. For diagnosing "this process is using all the +disk" or "this process is paging", **IO bytes is the actionable signal**. +Resident set (RSS) remains in the panel because it tracks actual +physical memory usage, which VIRT does not. + +### 46.5 Permission caveat (documented for future maintainers) + +`/proc/[pid]/io` requires `CAP_SYS_PTRACE` to read another UID's IO +counters on Linux. On Redox the proc scheme behavior is different and +may or may not enforce this. The helpers silently return 0 on read +failure so the column degrades gracefully — no panic, no missing-data +marker needed (the 0 itself communicates "IO counter unavailable"). + +--- + ## See Also - **`local/docs/RATATUI-APP-PATTERNS.md`** §13 — the canonical ratatui 0.30 best-practices update that this plan is derived from. Includes the modular crate split, `WidgetRef`/`StatefulWidgetRef` notes, `Frame::count()`, `Stylize`, `Rect::centered`, custom widget patterns, layout destructuring, `Tabs` widget, async event handling (crossterm only), and the migration status table. Use this as the implementation guide while this doc is the roadmap.