Andrei-Marius Radu wrote:
> Hello,
> 
> I wanted to make per cpu utilization graphs (using some perl scripts)
> so I ended up making this small patch (against -current) for sysctl(8)
> to add support for KERN_CPTIME2.
> 
> The per cpu utilization graphs problem can be solved in other ways, for
> example I found this old symon thread:
> marc.info/?l=openbsd-misc&m=116655627129555&w=2 however I think having
> KERN_CPTIME2 support is good anyway.
> 
> Is there anyone else who thinks this is needed/a good idea ?

For what it's worth, I was porting htop recently and I think I remember
it being painful to work without KERN_CPTIME2. I'd have to look back
(and look at this diff), though.

This should probably go to the tech@ list, by the way.

Thanks!

> Index: src/sbin/sysctl/sysctl.c
> ===================================================================
> RCS file: /cvs/src/sbin/sysctl/sysctl.c,v
> retrieving revision 1.211
> diff -u -p -u -r1.211 sysctl.c
> --- src/sbin/sysctl/sysctl.c    18 Apr 2015 18:28:37 -0000      1.211
> +++ src/sbin/sysctl/sysctl.c    28 Oct 2015 13:55:08 -0000
> @@ -215,6 +215,7 @@ int sysctl_emul(char *, char *, int);
>  #ifdef CPU_CHIPSET
>  int sysctl_chipset(char *, char **, int *, int, int *);
>  #endif
> +int sysctl_cptime2(char *, char **, int *, int, int *);
>  void vfsinit(void);
> 
>  char *equ = "=";
> @@ -412,6 +413,9 @@ parse(char *string, int flags)
>                         special |= LONGARRAY;
>                         lal = CPUSTATES;
>                         break;
> +               case KERN_CPTIME2:
> +                       sysctl_cptime2(string, &bufp, mib, flags,
> &type);
> +                       return;
>                 case KERN_SEMINFO:
>                         len = sysctl_seminfo(string, &bufp, mib, flags,
>                         &type);
>                         if (len < 0)
> @@ -2759,6 +2763,80 @@ sysctl_emul(char *string, char *newval,
>         return (0);
> 
> 
> +}
> +
> +int
> +sysctl_cptime2(char *string, char **bufpp, int mib[], int flags, int
> *typep)
> +{
> +       int local_mib[2], ncpu, i, cpu;
> +       size_t len;
> +       u_int64_t cp_time2[CPUSTATES];
> +       char *second, *third;
> +       const char *errstr;
> +
> +       local_mib[0] = CTL_HW;
> +       local_mib[1] = HW_NCPU;
> +       len = sizeof(ncpu);
> +       if (sysctl(local_mib, 2, &ncpu, &len, NULL, 0) == -1) {
> +               err(1, "%s can't get number of cpus (hw.ncpu)", string);
> +               return (0);
> +       }
> +
> +       len = sizeof(cp_time2);
> +       second = strchr(string, '.');
> +       if (!second) {
> +               errx(1, "%s: can't get mib second level name", string);
> +               return (0);
> +       }
> +       second++;
> +       third = strchr(second, '.');
> +       if (!third) {
> +               for (i = 0; i < ncpu; i++) {
> +                       mib[2] = i;
> +                       if (sysctl(mib, 3, &cp_time2, &len, NULL, 0) ==
> -1) {
> +                               warn("%s.%d can't get cpu states",
> string, i);
> +                               continue;
> +                       }
> +
> +                       printf("%s.%d=%ld,%ld,%ld,%ld,%ld\n", string, i,
> +                               cp_time2[CP_USER],
> +                               cp_time2[CP_NICE],
> +                               cp_time2[CP_SYS],
> +                               cp_time2[CP_INTR],
> +                               cp_time2[CP_IDLE]
> +                       );
> +               }
> +       }
> +       else {
> +               third++;
> +               if (ncpu > 1) {
> +                       cpu = strtonum(third, 0, ncpu - 1, &errstr);
> +               }
> +               else {
> +                       cpu = strtonum(third, 0, 0, &errstr);
> +               }
> +               if (errstr) {
> +                       errx(1, "%s: third level '%s' %s", string,
> third,
> +                               errstr);
> +                       return (0);
> +               }
> +
> +               mib[2] = cpu;
> +               if (sysctl(mib, 3, &cp_time2, &len, NULL, 0) == -1) {
> +                       warn("%s.%d can't get cpu states", string, i);
> +                       return (0);
> +               }
> +
> +               printf("%s=%ld,%ld,%ld,%ld,%ld\n", string,
> +                       cp_time2[CP_USER],
> +                       cp_time2[CP_NICE],
> +                       cp_time2[CP_SYS],
> +                       cp_time2[CP_INTR],
> +                       cp_time2[CP_IDLE]
> +               );
> +       }
> +
> +       return (1);
>  }
> 
>  static int
> Index: src/sbin/sysctl/sysctl.8
> ===================================================================
> RCS file: /cvs/src/sbin/sysctl/sysctl.8,v
> retrieving revision 1.187
> diff -u -p -u -r1.187 sysctl.8
> --- src/sbin/sysctl/sysctl.8    3 Oct 2015 09:17:13 -0000       1.187
> +++ src/sbin/sysctl/sysctl.8    28 Oct 2015 13:55:08 -0000
> @@ -153,6 +153,7 @@ and a few require a kernel compiled with
>  .It kern.malloc.kmemnames Ta string Ta no
>  .It kern.malloc.kmemstat.<name> Ta string Ta no
>  .It kern.cp_time Ta struct Ta no
> +.It kern.cp_time2 Ta struct Ta no
>  .It kern.nchstats Ta struct Ta no
>  .It kern.forkstat Ta struct Ta no
>  .It kern.nselcoll Ta integer Ta no

Reply via email to