Applied, thanks!
Samuel
David Bidner, le jeu. 17 sept. 2026 19:59:15 +0200, a ecrit:
> The aggregate "cpu" line of /proc/stat currently just repeats cpu0's
> values. As on Linux, it should be the sum over all CPUs: top, htop and
> other tools divide it by the number of CPUs to obtain the per-CPU
> average, so on SMP systems every reported CPU percentage was scaled by
> the number of CPUs (e.g. 800% for one busy core on an 8-CPU box).
>
> * procfs/rootdir.c (rootdir_gc_stat): read every CPU's idle time,
> sum them and emit the aggregate "cpu" line from the totals.
> ---
> procfs/rootdir.c | 47 +++++++++++++++++++++++++++++------------------
> 1 file changed, 29 insertions(+), 18 deletions(-)
>
> diff --git a/procfs/rootdir.c b/procfs/rootdir.c
> index 56e1906..fc2c607 100644
> --- a/procfs/rootdir.c
> +++ b/procfs/rootdir.c
> @@ -224,7 +224,9 @@ rootdir_gc_stat (void *hook, char **contents, ssize_t
> *contents_len)
> {
> struct timeval boottime, time, idletime;
> struct vm_statistics vmstats;
> - unsigned long up_ticks, idle_ticks;
> + unsigned long up_ticks;
> + unsigned long *idle_ticks;
> + unsigned long long total_idle;
> int i;
> FILE *m;
> host_basic_info_t basic;
> @@ -242,14 +244,28 @@ rootdir_gc_stat (void *hook, char **contents, ssize_t
> *contents_len)
> if (err)
> return err;
>
> - err = get_idletime (hook, &idletime, 0);
> - if (err)
> - return err;
> -
> err = vm_statistics (mach_task_self (), &vmstats);
> if (err)
> return EIO;
>
> + idle_ticks = malloc (basic->avail_cpus * sizeof *idle_ticks);
> + if (idle_ticks == NULL)
> + return ENOMEM;
> +
> + total_idle = 0;
> + for (i = 0; i < basic->avail_cpus; i++)
> + {
> + err = get_idletime (hook, &idletime, i);
> + if (err)
> + {
> + free (idle_ticks);
> + return err;
> + }
> +
> + idle_ticks[i] = opt_clk_tck * (idletime.tv_sec * 1000000. +
> idletime.tv_usec) / 1000000.;
> + total_idle += idle_ticks[i];
> + }
> +
> m = open_memstream (contents, (size_t *) contents_len);
> if (m == NULL)
> {
> @@ -259,22 +275,16 @@ rootdir_gc_stat (void *hook, char **contents, ssize_t
> *contents_len)
>
> timersub (&time, &boottime, &time);
> up_ticks = opt_clk_tck * (time.tv_sec * 1000000. + time.tv_usec) /
> 1000000.;
> - idle_ticks = opt_clk_tck * (idletime.tv_sec * 1000000. + idletime.tv_usec)
> / 1000000.;
>
> fprintf (m,
> - "cpu %lu 0 0 %lu 0 0 0 0 0\n"
> - "cpu0 %lu 0 0 %lu 0 0 0 0 0\n",
> - up_ticks - idle_ticks, idle_ticks,
> - up_ticks - idle_ticks, idle_ticks);
> + "cpu %llu 0 0 %llu 0 0 0 0 0\n",
> + (unsigned long long) basic->avail_cpus * up_ticks - total_idle,
> + total_idle);
>
> - for (i = 1; i < basic->avail_cpus; i++)
> - {
> - err = get_idletime (hook, &idletime, i);
> - idle_ticks = opt_clk_tck * (idletime.tv_sec * 1000000. +
> idletime.tv_usec) / 1000000.;
> - fprintf (m,
> - "cpu%d %lu 0 0 %lu 0 0 0 0 0\n",
> - i, up_ticks - idle_ticks, idle_ticks);
> - }
> + for (i = 0; i < basic->avail_cpus; i++)
> + fprintf (m,
> + "cpu%d %lu 0 0 %lu 0 0 0 0 0\n",
> + i, up_ticks - idle_ticks[i], idle_ticks[i]);
>
> fprintf (m,
> "intr 0\n"
> @@ -284,6 +294,7 @@ rootdir_gc_stat (void *hook, char **contents, ssize_t
> *contents_len)
> boottime.tv_sec);
>
> out:
> + free (idle_ticks);
> if (m)
> fclose (m);
> return err;
> --
> 2.47.3
>
>
--
Samuel
<erno> hm. I've lost a machine.. literally _lost_. it responds to ping, it
works completely, I just can't figure out where in my apartment it is.