mirror of https://github.com/xzeldon/htop.git
OpenBSD: support offline CPUs and hot-swapping
This commit is contained in:
parent
f608fc5c8a
commit
edf236f9fc
|
@ -36,12 +36,66 @@ static long fscale;
|
||||||
static int pageSize;
|
static int pageSize;
|
||||||
static int pageSizeKB;
|
static int pageSizeKB;
|
||||||
|
|
||||||
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, Hashtable* pidMatchList, uid_t userId) {
|
static void OpenBSDProcessList_updateCPUcount(ProcessList* super) {
|
||||||
|
OpenBSDProcessList* opl = (OpenBSDProcessList*) super;
|
||||||
const int nmib[] = { CTL_HW, HW_NCPU };
|
const int nmib[] = { CTL_HW, HW_NCPU };
|
||||||
const int mib[] = { CTL_HW, HW_NCPUONLINE };
|
const int mib[] = { CTL_HW, HW_NCPUONLINE };
|
||||||
const int fmib[] = { CTL_KERN, KERN_FSCALE };
|
|
||||||
int r;
|
int r;
|
||||||
unsigned int cpu_index_c = 0;
|
unsigned int value;
|
||||||
|
size_t size;
|
||||||
|
bool change = false;
|
||||||
|
|
||||||
|
size = sizeof(value);
|
||||||
|
r = sysctl(mib, 2, &value, &size, NULL, 0);
|
||||||
|
if (r < 0 || value < 1) {
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != super->activeCPUs) {
|
||||||
|
super->activeCPUs = value;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = sizeof(value);
|
||||||
|
r = sysctl(nmib, 2, &value, &size, NULL, 0);
|
||||||
|
if (r < 0 || value < 1) {
|
||||||
|
value = super->activeCPUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != super->existingCPUs) {
|
||||||
|
opl->cpuData = xReallocArray(opl->cpuData, value + 1, sizeof(CPUData));
|
||||||
|
super->existingCPUs = value;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change) {
|
||||||
|
CPUData* dAvg = &opl->cpuData[0];
|
||||||
|
memset(dAvg, '\0', sizeof(CPUData));
|
||||||
|
dAvg->totalTime = 1;
|
||||||
|
dAvg->totalPeriod = 1;
|
||||||
|
dAvg->online = true;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < super->existingCPUs; i++) {
|
||||||
|
CPUData* d = &opl->cpuData[i + 1];
|
||||||
|
memset(d, '\0', sizeof(CPUData));
|
||||||
|
d->totalTime = 1;
|
||||||
|
d->totalPeriod = 1;
|
||||||
|
|
||||||
|
const int ncmib[] = { CTL_KERN, KERN_CPUSTATS, i };
|
||||||
|
struct cpustats cpu_stats;
|
||||||
|
|
||||||
|
size = sizeof(cpu_stats);
|
||||||
|
if (sysctl(ncmib, 3, &cpu_stats, &size, NULL, 0) < 0) {
|
||||||
|
CRT_fatalError("ncmib sysctl call failed");
|
||||||
|
}
|
||||||
|
d->online = (cpu_stats.cs_flags & CPUSTATS_ONLINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, Hashtable* pidMatchList, uid_t userId) {
|
||||||
|
const int fmib[] = { CTL_KERN, KERN_FSCALE };
|
||||||
size_t size;
|
size_t size;
|
||||||
char errbuf[_POSIX2_LINE_MAX];
|
char errbuf[_POSIX2_LINE_MAX];
|
||||||
|
|
||||||
|
@ -49,20 +103,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, H
|
||||||
ProcessList* pl = (ProcessList*) opl;
|
ProcessList* pl = (ProcessList*) opl;
|
||||||
ProcessList_init(pl, Class(OpenBSDProcess), usersTable, dynamicMeters, pidMatchList, userId);
|
ProcessList_init(pl, Class(OpenBSDProcess), usersTable, dynamicMeters, pidMatchList, userId);
|
||||||
|
|
||||||
// TODO: test offline CPUs and hot swapping
|
OpenBSDProcessList_updateCPUcount(pl);
|
||||||
|
|
||||||
size = sizeof(pl->activeCPUs);
|
|
||||||
r = sysctl(mib, 2, &pl->activeCPUs, &size, NULL, 0);
|
|
||||||
if (r < 0 || pl->activeCPUs < 1) {
|
|
||||||
pl->activeCPUs = 1;
|
|
||||||
}
|
|
||||||
opl->cpus = xCalloc(pl->activeCPUs + 1, sizeof(CPUData));
|
|
||||||
|
|
||||||
size = sizeof(int);
|
|
||||||
r = sysctl(nmib, 2, &pl->existingCPUs, &size, NULL, 0);
|
|
||||||
if (r < 0) {
|
|
||||||
pl->existingCPUs = pl->activeCPUs;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = sizeof(fscale);
|
size = sizeof(fscale);
|
||||||
if (sysctl(fmib, 2, &fscale, &size, NULL, 0) < 0) {
|
if (sysctl(fmib, 2, &fscale, &size, NULL, 0) < 0) {
|
||||||
|
@ -73,12 +114,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, H
|
||||||
CRT_fatalError("pagesize sysconf call failed");
|
CRT_fatalError("pagesize sysconf call failed");
|
||||||
pageSizeKB = pageSize / ONE_K;
|
pageSizeKB = pageSize / ONE_K;
|
||||||
|
|
||||||
for (unsigned int i = 0; i <= pl->activeCPUs; i++) {
|
|
||||||
CPUData* d = opl->cpus + i;
|
|
||||||
d->totalTime = 1;
|
|
||||||
d->totalPeriod = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
opl->kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
|
opl->kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
|
||||||
if (opl->kd == NULL) {
|
if (opl->kd == NULL) {
|
||||||
CRT_fatalError("kvm_openfiles() failed");
|
CRT_fatalError("kvm_openfiles() failed");
|
||||||
|
@ -86,23 +121,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, H
|
||||||
|
|
||||||
opl->cpuSpeed = -1;
|
opl->cpuSpeed = -1;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pl->existingCPUs; i++) {
|
|
||||||
const int ncmib[] = { CTL_KERN, KERN_CPUSTATS, i };
|
|
||||||
struct cpustats cpu_stats;
|
|
||||||
|
|
||||||
size = sizeof(cpu_stats);
|
|
||||||
if (sysctl(ncmib, 3, &cpu_stats, &size, NULL, 0) < 0) {
|
|
||||||
CRT_fatalError("ncmib sysctl call failed");
|
|
||||||
}
|
|
||||||
if (cpu_stats.cs_flags & CPUSTATS_ONLINE) {
|
|
||||||
opl->cpus[cpu_index_c].cpuIndex = i;
|
|
||||||
cpu_index_c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_index_c == pl->activeCPUs)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pl;
|
return pl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +131,7 @@ void ProcessList_delete(ProcessList* this) {
|
||||||
kvm_close(opl->kd);
|
kvm_close(opl->kd);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(opl->cpus);
|
free(opl->cpuData);
|
||||||
|
|
||||||
ProcessList_done(this);
|
ProcessList_done(this);
|
||||||
free(this);
|
free(this);
|
||||||
|
@ -275,8 +293,6 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
|
||||||
Process* proc = ProcessList_getProcess(&this->super, (kproc->p_tid == -1) ? kproc->p_pid : kproc->p_tid, &preExisting, OpenBSDProcess_new);
|
Process* proc = ProcessList_getProcess(&this->super, (kproc->p_tid == -1) ? kproc->p_pid : kproc->p_tid, &preExisting, OpenBSDProcess_new);
|
||||||
OpenBSDProcess* fp = (OpenBSDProcess*) proc;
|
OpenBSDProcess* fp = (OpenBSDProcess*) proc;
|
||||||
|
|
||||||
proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
|
|
||||||
|
|
||||||
if (!preExisting) {
|
if (!preExisting) {
|
||||||
proc->ppid = kproc->p_ppid;
|
proc->ppid = kproc->p_ppid;
|
||||||
proc->tpgid = kproc->p_tpgid;
|
proc->tpgid = kproc->p_tpgid;
|
||||||
|
@ -348,11 +364,13 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
|
||||||
if (proc->state == 'R') {
|
if (proc->state == 'R') {
|
||||||
this->super.runningTasks++;
|
this->super.runningTasks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
|
||||||
proc->updated = true;
|
proc->updated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getKernelCPUTimes(int cpuId, u_int64_t* times) {
|
static void getKernelCPUTimes(unsigned int cpuId, u_int64_t* times) {
|
||||||
const int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId };
|
const int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId };
|
||||||
size_t length = sizeof(*times) * CPUSTATES;
|
size_t length = sizeof(*times) * CPUSTATES;
|
||||||
if (sysctl(mib, 3, times, &length, NULL, 0) == -1 || length != sizeof(*times) * CPUSTATES) {
|
if (sysctl(mib, 3, times, &length, NULL, 0) == -1 || length != sizeof(*times) * CPUSTATES) {
|
||||||
|
@ -401,9 +419,14 @@ static void OpenBSDProcessList_scanCPUTime(OpenBSDProcessList* this) {
|
||||||
u_int64_t kernelTimes[CPUSTATES] = {0};
|
u_int64_t kernelTimes[CPUSTATES] = {0};
|
||||||
u_int64_t avg[CPUSTATES] = {0};
|
u_int64_t avg[CPUSTATES] = {0};
|
||||||
|
|
||||||
for (unsigned int i = 0; i < this->super.activeCPUs; i++) {
|
for (unsigned int i = 0; i < this->super.existingCPUs; i++) {
|
||||||
getKernelCPUTimes(this->cpus[i].cpuIndex, kernelTimes);
|
CPUData* cpu = &this->cpuData[i + 1];
|
||||||
CPUData* cpu = this->cpus + i + 1;
|
|
||||||
|
if (!cpu->online) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
getKernelCPUTimes(i, kernelTimes);
|
||||||
kernelCPUTimesToHtop(kernelTimes, cpu);
|
kernelCPUTimesToHtop(kernelTimes, cpu);
|
||||||
|
|
||||||
avg[CP_USER] += cpu->userTime;
|
avg[CP_USER] += cpu->userTime;
|
||||||
|
@ -420,7 +443,7 @@ static void OpenBSDProcessList_scanCPUTime(OpenBSDProcessList* this) {
|
||||||
avg[i] /= this->super.activeCPUs;
|
avg[i] /= this->super.activeCPUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
kernelCPUTimesToHtop(avg, this->cpus);
|
kernelCPUTimesToHtop(avg, &this->cpuData[0]);
|
||||||
|
|
||||||
{
|
{
|
||||||
const int mib[] = { CTL_HW, HW_CPUSPEED };
|
const int mib[] = { CTL_HW, HW_CPUSPEED };
|
||||||
|
@ -437,6 +460,7 @@ static void OpenBSDProcessList_scanCPUTime(OpenBSDProcessList* this) {
|
||||||
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
OpenBSDProcessList* opl = (OpenBSDProcessList*) super;
|
OpenBSDProcessList* opl = (OpenBSDProcessList*) super;
|
||||||
|
|
||||||
|
OpenBSDProcessList_updateCPUcount(super);
|
||||||
OpenBSDProcessList_scanMemoryInfo(super);
|
OpenBSDProcessList_scanMemoryInfo(super);
|
||||||
OpenBSDProcessList_scanCPUTime(opl);
|
OpenBSDProcessList_scanCPUTime(opl);
|
||||||
|
|
||||||
|
@ -452,11 +476,5 @@ bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) {
|
||||||
assert(id < super->existingCPUs);
|
assert(id < super->existingCPUs);
|
||||||
|
|
||||||
const OpenBSDProcessList* opl = (const OpenBSDProcessList*) super;
|
const OpenBSDProcessList* opl = (const OpenBSDProcessList*) super;
|
||||||
|
return opl->cpuData[id + 1].online;
|
||||||
for (unsigned int i = 0; i < super->activeCPUs; i++) {
|
|
||||||
if (opl->cpus[i].cpuIndex == id)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,14 +36,14 @@ typedef struct CPUData_ {
|
||||||
unsigned long long int intrPeriod;
|
unsigned long long int intrPeriod;
|
||||||
unsigned long long int idlePeriod;
|
unsigned long long int idlePeriod;
|
||||||
|
|
||||||
unsigned int cpuIndex;
|
bool online;
|
||||||
} CPUData;
|
} CPUData;
|
||||||
|
|
||||||
typedef struct OpenBSDProcessList_ {
|
typedef struct OpenBSDProcessList_ {
|
||||||
ProcessList super;
|
ProcessList super;
|
||||||
kvm_t* kd;
|
kvm_t* kd;
|
||||||
|
|
||||||
CPUData* cpus;
|
CPUData* cpuData;
|
||||||
int cpuSpeed;
|
int cpuSpeed;
|
||||||
|
|
||||||
} OpenBSDProcessList;
|
} OpenBSDProcessList;
|
||||||
|
|
|
@ -169,19 +169,12 @@ int Platform_getMaxPid() {
|
||||||
|
|
||||||
double Platform_setCPUValues(Meter* this, unsigned int cpu) {
|
double Platform_setCPUValues(Meter* this, unsigned int cpu) {
|
||||||
const OpenBSDProcessList* pl = (const OpenBSDProcessList*) this->pl;
|
const OpenBSDProcessList* pl = (const OpenBSDProcessList*) this->pl;
|
||||||
const CPUData* cpuData = NULL;
|
const CPUData* cpuData = &(pl->cpuData[cpu]);
|
||||||
double total;
|
double total;
|
||||||
double totalPercent;
|
double totalPercent;
|
||||||
double* v = this->values;
|
double* v = this->values;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pl->super.activeCPUs; i++) {
|
if (!cpuData->online) {
|
||||||
if (pl->cpus[i].cpuIndex == cpu) {
|
|
||||||
cpuData = &(pl->cpus[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cpuData) {
|
|
||||||
this->curItems = 0;
|
this->curItems = 0;
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue