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.
200 lines
5.0 KiB
200 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) ==========
|
|
|