static void fill_pcpu(struct pcpu ***pcpup, int* maxcpup) { struct pcpu **pcpu; int maxcpu, i; *pcpup = NULL; if (kd == NULL) return; maxcpu = kvm_getmaxcpu(kd); if (maxcpu < 0) errx(1, "kvm_getmaxcpu: %s", kvm_geterr(kd)); pcpu = calloc(maxcpu, sizeof(struct pcpu *)); if (pcpu == NULL) err(1, "calloc"); for (i = 0; i < maxcpu; i++) { pcpu[i] = kvm_getpcpu(kd, i); if (pcpu[i] == (struct pcpu *)-1) errx(1, "kvm_getpcpu: %s", kvm_geterr(kd)); } *maxcpup = maxcpu; *pcpup = pcpu; }
int kvm_getcptime(kvm_t *kd, long *cp_time) { struct pcpu *pc; int i, j, maxcpu; if (kd == NULL) { kvm_cp_time_cached = 0; return (0); } if (ISALIVE(kd)) return (getsysctl(kd, "kern.cp_time", cp_time, sizeof(long) * CPUSTATES)); if (!kd->arch->ka_native(kd)) { _kvm_err(kd, kd->program, "cannot read cp_time from non-native core"); return (-1); } if (kvm_cp_time_cached == 0) { if (_kvm_cp_time_init(kd) < 0) return (-1); } /* If this kernel has a "cp_time[]" symbol, then just read that. */ if (kvm_cp_time_nl[NL_CP_TIME].n_value != 0) { if (kvm_read(kd, kvm_cp_time_nl[NL_CP_TIME].n_value, cp_time, sizeof(long) * CPUSTATES) != sizeof(long) * CPUSTATES) { _kvm_err(kd, kd->program, "cannot read cp_time array"); return (-1); } return (0); } /* * If we don't have that symbol, then we have to simulate * "cp_time[]" by adding up the individual times for each CPU. */ maxcpu = kvm_getmaxcpu(kd); if (maxcpu < 0) return (-1); for (i = 0; i < CPUSTATES; i++) cp_time[i] = 0; for (i = 0; i < maxcpu; i++) { pc = kvm_getpcpu(kd, i); if (pc == NULL) continue; if (pc == (void *)-1) return (-1); for (j = 0; j < CPUSTATES; j++) cp_time[j] += pc->pc_cp_time[j]; free(pc); } return (0); }
int machine_get_smpload(load_type * result, int *numcpus) { int i, num; size_t size; load_type load; #ifdef HAVE_SYS_PCPU_H static load_type last_load[MAX_CPUS]; struct pcpu *pcpudata; if (kvmd == NULL) return (FALSE); #endif if (numcpus == NULL) return (FALSE); size = sizeof(int); if (sysctlbyname("hw.ncpu", &num, &size, NULL, 0) < 0) { perror("sysctl hw.ncpu"); return (FALSE); } /* restrict #CPUs to max. *numcpus */ num = (*numcpus >= num) ? num : *numcpus; *numcpus = num; #ifndef HAVE_SYS_PCPU_H if (machine_get_load(&load) == FALSE) return (FALSE); #endif for (i = 0; i < num; i++) { #ifdef HAVE_SYS_PCPU_H pcpudata = kvm_getpcpu(kvmd, i); if (pcpudata == NULL || pcpudata == (void *)-1) return (FALSE); /* extract the data for single CPU */ load.user = (unsigned long)(pcpudata->pc_cp_time[CP_USER]); load.nice = (unsigned long)(pcpudata->pc_cp_time[CP_NICE]); load.system = (unsigned long)(pcpudata->pc_cp_time[CP_SYS] + pcpudata->pc_cp_time[CP_INTR]); load.idle = (unsigned long)(pcpudata->pc_cp_time[CP_IDLE]); load.total = load.user + load.nice + load.system + load.idle; /* store difference in result */ result[i].user = load.user - last_load[i].user; result[i].nice = load.nice - last_load[i].nice; result[i].system = load.system - last_load[i].system; result[i].idle = load.idle - last_load[i].idle; result[i].total = load.total - last_load[i].total; /* store current value for next round */ last_load[i].user = load.user; last_load[i].nice = load.nice; last_load[i].system = load.system; last_load[i].idle = load.idle; last_load[i].total = load.total; /* free pcpu buffer */ free(pcpudata); #else result[i] = load; #endif } return (TRUE); }