redbear-power: v1.22 sort by IO (per-process read+write bytes)
Process tab gains a new IO column sourced from /proc/[pid]/io read_bytes and write_bytes, summing them as a single sortable value. - New fields on ProcessInfo: io_read_kb, io_write_kb - New method: ProcessInfo::io_total_kb() - New helpers: read_io_bytes, write_io_bytes (silent on failure; /proc/[pid]/io may require CAP_SYS_PTRACE for owned UID) - New SortMode::Io variant inserted into the cycle (Rss -> Cpu -> Io -> Pid -> Name) - Updated render header: VIRT replaced by IO (RSS preserved) - 4 new unit tests; total 80 pass - Redox stripped binary: 4123496 bytes - Linux smoke test confirms opencode dominates IO, kscreenlocker_g shows 0.0 KiB Docs: local/docs/redbear-power-improvement-plan.md \xC2\xA746
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user