You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.0 KiB
201 lines
5.0 KiB
|
|
/***************************************************************************
|
|
* *
|
|
* KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
|
|
* (c) 2002, Ben Burton *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "kcpuproc.h"
|
|
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
// BSD-specific includes.
|
|
#ifdef Q_OS_BSD4
|
|
#include <sys/param.h>
|
|
#if defined(__FreeBSD__) && __FreeBSD_version >= 500101
|
|
#include <sys/resource.h>
|
|
#else
|
|
#include <sys/dkstat.h>
|
|
#endif
|
|
#include <sys/sysctl.h>
|
|
#include <string.h>
|
|
#include <kvm.h>
|
|
#ifdef Q_OS_NETBSD
|
|
#include <sys/sched.h>
|
|
#endif
|
|
#endif
|
|
|
|
/**
|
|
* Linux
|
|
* -----
|
|
*
|
|
* System information is read from /proc/stat.
|
|
*
|
|
* We assume /proc/stat is in one of the following formats:
|
|
*
|
|
* cpu %d %d %d %d
|
|
* ....
|
|
*
|
|
* cpu %d %d %d %d
|
|
* cpu0 %d %d %d %d
|
|
* ....
|
|
*
|
|
* cpu %d %d %d %d
|
|
* cpu0 %d %d %d %d
|
|
* cpu1 %d %d %d %d
|
|
* ....
|
|
*
|
|
* where each set of four numbers is of the form:
|
|
*
|
|
* user_ticks nice_ticks system_ticks idle_ticks
|
|
*
|
|
* We also allow sets of seven numbers instead of four (as provided by
|
|
* the 2.6 kernel); the last three of these numbers are ignored.
|
|
*
|
|
* BSD
|
|
* ---
|
|
*
|
|
* Currently only uni-processor mode is supported for BSD.
|
|
*
|
|
* BSD code by Andy Fawcett <andy@athame.co.uk> and
|
|
* Robbie Ward <linuxphreak@gmx.co.uk>, licensed under GPL2.
|
|
*
|
|
* Other Operating Systems
|
|
* -----------------------
|
|
*
|
|
* Please, send in a patch!
|
|
*
|
|
* The KCPULoad maintainer is currently Ben Burton <bab@debian.org>, or
|
|
* you could submit a patch through the KDE bug tracking system
|
|
* (bugs.kde.org).
|
|
*/
|
|
|
|
KCPUProc::CPU::Ticks::Ticks() :
|
|
U(0), S(0), N(0), I(0)
|
|
{ }
|
|
|
|
KCPUProc::KCPUProc() {
|
|
smp = false;
|
|
|
|
// Look for SMP support and take a current tick reading.
|
|
|
|
// ========== BSD-specific (begin) ==========
|
|
#ifdef Q_OS_BSD4
|
|
readLoad();
|
|
return;
|
|
#endif
|
|
// ========== BSD-specific (end) ==========
|
|
|
|
// ========== Linux-specific (begin) ==========
|
|
#ifdef Q_OS_LINUX
|
|
if ((fd = fopen("/proc/stat", "r")) == 0)
|
|
return;
|
|
|
|
if (!all.parse(fd))
|
|
return;
|
|
CPU c;
|
|
while (c.parse(fd))
|
|
cpu.push_back(c);
|
|
smp = cpu.size() > 1;
|
|
#endif
|
|
// ========== Linux-specific (end) ==========
|
|
}
|
|
|
|
void KCPUProc::readLoad() {
|
|
// OS-specific local variables.
|
|
|
|
// ========== Linux-specific (begin) ==========
|
|
#ifdef Q_OS_LINUX
|
|
// Prepare to take the readings.
|
|
|
|
if ((fd = fopen("/proc/stat", "r")) == 0)
|
|
return;
|
|
|
|
// Take a fresh set of current readings (SMP mode).
|
|
|
|
all.parse(fd);
|
|
for (int i = 0; i < cpu.size(); i++) {
|
|
if (!cpu[i].parse(fd))
|
|
break;
|
|
}
|
|
|
|
// Clean up after taking readings.
|
|
|
|
fclose(fd);
|
|
#endif
|
|
// ========== Linux-specific (end) ==========
|
|
|
|
// ========== BSD-specific (begin) ==========
|
|
#ifdef Q_OS_BSD4
|
|
static int name2oid[2] = { 0, 3 };
|
|
static int oidCpuTime[CTL_MAXNAME + 2];
|
|
static size_t oidCpuTimeLen = sizeof(oidCpuTime);
|
|
long cpuTime[CPUSTATES];
|
|
size_t cpuTimeLen = sizeof(cpuTime);
|
|
static char *name = "kern.cp_time";
|
|
static int initialized = 0;
|
|
|
|
if(smp) {
|
|
// Take a fresh set of current readings (SMP mode).
|
|
// TODO: Add SMP support for BSD.
|
|
} else {
|
|
// Take a fresh set of current readings (uni-processor mode).
|
|
|
|
// The current readings must now become the previous readings.
|
|
all.p = all.c;
|
|
|
|
if (! initialized) {
|
|
if (sysctl(name2oid, 2, oidCpuTime, &oidCpuTimeLen, name,
|
|
strlen(name)) < 0)
|
|
return;
|
|
|
|
oidCpuTimeLen /= sizeof(int);
|
|
initialized = 1;
|
|
}
|
|
|
|
if (sysctl(oidCpuTime, oidCpuTimeLen, cpuTime, &cpuTimeLen, 0, 0) < 0)
|
|
return;
|
|
|
|
all.c.U = cpuTime[CP_USER];
|
|
all.c.N = cpuTime[CP_NICE];
|
|
all.c.S = cpuTime[CP_SYS];
|
|
all.c.I = cpuTime[CP_IDLE];
|
|
}
|
|
#endif
|
|
// ========== BSD-specific (end) ==========
|
|
}
|
|
|
|
// ========== Linux-specific (begin) ==========
|
|
#ifdef Q_OS_LINUX
|
|
bool KCPUProc::CPU::parse(FILE* fd) {
|
|
char tagbuffer[32+1];
|
|
Ticks n; // new ticks
|
|
if (fscanf(fd, "%32s%d%d%d%d", tagbuffer, &n.U, &n.N, &n.S, &n.I) != 5) {
|
|
return false; // failure
|
|
}
|
|
|
|
if (strncmp(tagbuffer, "cpu", 3) != 0) {
|
|
return false; // tag mismatch
|
|
}
|
|
|
|
// shift readings
|
|
p = c;
|
|
c = n;
|
|
|
|
// ignore the rest of the line
|
|
int ch;
|
|
do {
|
|
ch = getc(fd);
|
|
} while (ch != '\n' && ch != EOF);
|
|
return true;
|
|
}
|
|
#endif
|
|
// ========== Linux-specific (end) ==========
|