jcp-energy: meter a closure's CPU work with the per-process energy counter, which macOS 27 keeps live #122
Loading…
Reference in a new issue
No description provided.
Delete branch "jcp-energy/process-energy"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
On macOS 27 an unprivileged process sees IOReport's CPU rails republished only in lumps, so #110 makes jcp-energy fall back to time×power there. The kernel keeps a per-process counter,
ri_energy_njfromproc_pid_rusage(getpid(), RUSAGE_INFO_V6), and that one is live. It is a public libproc call, with no privilege.Meter::measure(closure)runs its work in-process, so a per-process reading is the work's own CPU energy.The rung
Meter::ProcessEnergyreadsri_energy_njaround the closure and grades the figure HwShunt.Rung,Meter::rung(),Detection,Meter::detect_explained().Measured (macOS 27.0.1)
Live(12 intervals, 315 ms)Live(12 intervals, 300 ms)yes, 200 ms)Mutations caught (11):
detect;jcp-intercept, jcp-schema and jcp-conformance are green, and the conformance binary prints "all checks passed".
Behaviour change: on macOS,
detect()now selects this rung and never probes IOReport. A span shorter than the counter's ~0.5 ms update falls back to the model.Updates
830fc085: a span where children did work is Partial. The span is graded Whole only if the process's reaped-children CPU time held and no child is alive at span end; otherwise it isEnergy::measured_partial.yesgives Partial at 1,322 µJ (the child's own 1.246 J is excluded), a child left running gives Partial, and a pure burn gives Whole at 1.366 J.posix_spawn.22e5a6ad: the one-thread test's floor is 0.1 J. The burn already counts 200 ms of the thread's own CPU, but the energy that costs ranges 0.18–1.24 J by core class. The kernel caps a test binary at default QoS, so asking for user-interactive does nothing. The floor is now 0.1 J, still the sleeping test's ceiling. All 5 runs pass under 18 spinners.🤖 Generated with Claude Code
c3bf64ec40e22f42721ee22f42721e05b996fdf405b996fdf4830fc085f2