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.

Reply via email to