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