Skip to content

feat: rootless GPU utilization token ($sys_gpu) - #3

Open
Cyb3rDudu wants to merge 2 commits into
getpipher:mainfrom
Cyb3rDudu:main
Open

Cyb3rDudu wants to merge 2 commits into
getpipher:mainfrom
Cyb3rDudu:main

Conversation

@Cyb3rDudu

Copy link
Copy Markdown

What

Adds a $sys_gpu sidebar token: GPU utilization 0-100% on Apple Silicon, read rootless from the IORegistry through a small bundled C helper — no sudo, no powermetrics, no private framework linkage.

How

  • bin/gpu-util.c (~90 lines): recursive IORegistryEntrySearchCFProperty for the accelerator's PerformanceStatistics property, then reads Device Utilization % from the nested dict. Uses only public IOKit/CoreFoundation APIs.
  • Matching is by property, not class name — chip-specific classes like AGXAcceleratorG14X change per GPU generation; the property search survives new SoCs unchanged.
  • scripts/metrics.sh: sys_gpu() collector with the usual never-empty -- fallback (also covers Linux until native reads land in v0.2).
  • scripts/poll.sh: collects and pushes sys_gpu alongside sys_cpu.
  • config/sidebar.toml.snippet: metric rows regrouped to [gpu cpu mem] and [batt net disk].

Why rootless matters

powermetrics needs root, which forces a background poller into either a sudoers entry or a root daemon. The IORegistry path needs neither: verified against ioreg output on an M2 Max (values track within sampling jitter), ~9ms per read in the common case, worst case ~330ms — fine at the default 5s cadence.

Notes

  • A prebuilt arm64 binary is bundled; clang rebuilds it when available.
  • No new runtime dependencies (no jq additions, no brew packages).

Cyb3rDudu and others added 2 commits August 29, 2026 23:59
Adds $sys_gpu to the sidebar: GPU utilization 0-100% on Apple Silicon,
read rootless from the IORegistry (PerformanceStatistics on the AGX
accelerator) through a small bundled C helper that uses only public
IOKit/CoreFoundation APIs — no sudo and no powermetrics required.

- bin/gpu-util.c: recursive property search for PerformanceStatistics,
  then reads "Device Utilization %" from the nested dict. Matching by
  property instead of the chip-specific class name (AGXAcceleratorG14X,
  …) keeps it working across GPU generations. ~9-330ms per read.
- scripts/metrics.sh: sys_gpu collector with the usual never-empty "--"
  fallback (also covers Linux until native reads land in v0.2).
- scripts/poll.sh: collects and pushes sys_gpu alongside sys_cpu.
- config/sidebar.toml.snippet: metrics regrouped into
  [gpu cpu mem] and [batt net disk] rows.

Co-authored-by: dudu <dudu@users.noreply.github.com>
- herdr >= 0.8 workspace list carries no workspace_id field; derive the
  id from active_tab_id ("w3:t1" -> "w3") with label fallback. Without
  this the poller logged 'no workspaces found' forever and never pushed.
- include sys_gpu in the collected tokens, never-empty guard, and the
  report-metadata push (the collector existed but was never wired into
  push_all).

Co-authored-by: dudu <dudu@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant