Describe the bug
cpu.TestTimes fails on OpenBSD on any host with 4 or more online CPUs:
--- FAIL: TestTimes (0.00s)
cpu_test.go:51: {"cpu":"cpu-total","user":22.4,"system":17.2,"idle":10.7,...}
cpu_test.go:57: Relative error is too high: 2 (expected) < 3.001336302895323 (actual)
cpu_test.go:60: Relative error is too high: 2 (expected) < 3 (actual)
cpu_test.go:63: Relative error is too high: 2 (expected) < 3.000000000000001 (actual)
The relative error is exactly ncpu - 1. hw.ncpu was 4 on that host, and all
three fields came out at 3.0.
To Reproduce
// on OpenBSD, on a host with 4 or more online CPUs
total, _ := cpu.Times(false) // KERN_CPTIME
per, _ := cpu.Times(true) // KERN_CPUSTATS, one per CPU
// sum(per) == ncpu * total[0]
Expected behavior
The test asserts that the per-CPU times sum to roughly cpu-total, with
margin = 2.0. On OpenBSD they do not, because the two paths are not on the
same scale: KERN_CPTIME is averaged over the online CPUs. From
sys/kern/kern_sysctl.c (lines 653-675):
case KERN_CPTIME:
CPU_INFO_FOREACH(cii, ci) {
if (!cpu_is_online(ci))
continue;
n++;
sysctl_ci_cp_time(ci, ci_cp_time);
for (i = 0; i < CPUSTATES; i++)
cp_time[i] += ci_cp_time[i];
}
for (i = 0; i < CPUSTATES; i++)
cp_time[i] /= n;
https://github.com/openbsd/src/blob/master/sys/kern/kern_sysctl.c
So sum(perCPU) == ncpu * cpuTotal, and margin = 2.0 only holds while
ncpu <= 3.
This may be more than a test tolerance. On Linux, cpu-total comes from
the cpu line of /proc/stat, which is the sum across CPUs. If OpenBSD
returns the average, cpu.Times(false) means something different there. It
cancels out in a percentage computed over two samples, so it may not matter in
practice -- your call.
If you do want a sum, KERN_CPTIME2 returns un-averaged per-CPU times, and
cpu_openbsd.go already reads hw.ncpuonline elsewhere, which is the same
divisor the kernel uses.
Environment (please complete the following information):
Additional context
Found while running the suite on OpenBSD for the first time:
https://github.com/neilpang/gopsutil/actions/runs/30751019667/job/91504958976
Filed separately from the Process.Times() panic, since they are unrelated.
Describe the bug
cpu.TestTimesfails on OpenBSD on any host with 4 or more online CPUs:The relative error is exactly
ncpu - 1.hw.ncpuwas 4 on that host, and allthree fields came out at 3.0.
To Reproduce
Expected behavior
The test asserts that the per-CPU times sum to roughly
cpu-total, withmargin = 2.0. On OpenBSD they do not, because the two paths are not on thesame scale:
KERN_CPTIMEis averaged over the online CPUs. Fromsys/kern/kern_sysctl.c(lines 653-675):https://github.com/openbsd/src/blob/master/sys/kern/kern_sysctl.c
So
sum(perCPU) == ncpu * cpuTotal, andmargin = 2.0only holds whilencpu <= 3.This may be more than a test tolerance. On Linux,
cpu-totalcomes fromthe
cpuline of/proc/stat, which is the sum across CPUs. If OpenBSDreturns the average,
cpu.Times(false)means something different there. Itcancels out in a percentage computed over two samples, so it may not matter in
practice -- your call.
If you do want a sum,
KERN_CPTIME2returns un-averaged per-CPU times, andcpu_openbsd.goalready readshw.ncpuonlineelsewhere, which is the samedivisor the kernel uses.
Environment (please complete the following information):
hw.ncpu=4Additional context
Found while running the suite on OpenBSD for the first time:
https://github.com/neilpang/gopsutil/actions/runs/30751019667/job/91504958976
Filed separately from the
Process.Times()panic, since they are unrelated.