top: Use a cpuset_t to represent a CPU mask

The code attempts to detect holes in the CPU ID space, but previously
this would only work for up to sizeof(long)*8 CPUs.

MFC after:	2 weeks
This commit is contained in:
Mark Johnston 2023-05-26 15:14:21 -04:00
parent 14c5cf3a16
commit e96ed17746

View file

@ -16,9 +16,10 @@
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/cpuset.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/param.h>
#include <sys/priority.h>
#include <sys/proc.h>
#include <sys/resource.h>
@ -204,7 +205,7 @@ static const char *ordernames[] = {
static int maxcpu;
static int maxid;
static int ncpus;
static unsigned long cpumask;
static cpuset_t cpumask;
static long *times;
static long *pcpu_cp_time;
static long *pcpu_cp_old;
@ -347,8 +348,6 @@ machine_init(struct statics *statics)
statics->order_names = ordernames;
/* Allocate state for per-CPU stats. */
cpumask = 0;
ncpus = 0;
GETSYSCTL("kern.smp.maxcpus", maxcpu);
times = calloc(maxcpu * CPUSTATES, sizeof(long));
if (times == NULL)
@ -357,18 +356,18 @@ machine_init(struct statics *statics)
if (sysctlbyname("kern.cp_times", times, &size, NULL, 0) == -1)
err(1, "sysctlbyname kern.cp_times");
pcpu_cp_time = calloc(1, size);
maxid = (size / CPUSTATES / sizeof(long)) - 1;
maxid = MIN(size / CPUSTATES / sizeof(long) - 1, CPU_SETSIZE - 1);
CPU_ZERO(&cpumask);
for (i = 0; i <= maxid; i++) {
empty = 1;
for (j = 0; empty && j < CPUSTATES; j++) {
if (times[i * CPUSTATES + j] != 0)
empty = 0;
}
if (!empty) {
cpumask |= (1ul << i);
ncpus++;
}
if (!empty)
CPU_SET(i, &cpumask);
}
ncpus = CPU_COUNT(&cpumask);
assert(ncpus > 0);
pcpu_cp_old = calloc(ncpus * CPUSTATES, sizeof(long));
pcpu_cp_diff = calloc(ncpus * CPUSTATES, sizeof(long));
@ -466,7 +465,7 @@ get_system_info(struct system_info *si)
/* convert cp_time counts to percentages */
for (i = j = 0; i <= maxid; i++) {
if ((cpumask & (1ul << i)) == 0)
if (!CPU_ISSET(i, &cpumask))
continue;
percentages(CPUSTATES, &pcpu_cpu_states[j * CPUSTATES],
&pcpu_cp_time[j * CPUSTATES],