2
KSysGuard, the KDE System Guard
4
Copyright (c) 2000-2001 Chris Schlaeger <cs@kde.org>
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of version 2 of the GNU General Public
8
License as published by the Free Software Foundation.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
#include <sys/types.h>
32
#include "ksysguardd.h"
36
static int CpuInfoOK = 0;
37
static int numProcessors = 0; /* Total number of physical processors */
38
static int HighNumProcessors = 0; /* Highest # number of physical processors ever seen */
39
static int numCores = 0; /* Total # of cores */
40
static int HighNumCores = 0; /* Highest # of cores ever seen */
41
static float* Clocks = 0; /* Array with one entry per core */
43
#define CPUINFOBUFSIZE (32 * 1024)
44
static char CpuInfoBuf[ CPUINFOBUFSIZE ];
46
static struct SensorModul *CpuInfoSM;
48
static void processCpuInfo( void )
53
char* cibp = CpuInfoBuf;
55
/* coreUniqueId is not per processor; it is a counter of the number of cores encountered
56
* by the parse thus far */
59
/* Reset global variables */
66
sprintf( format, "%%%d[^:]: %%%d[^\n]\n", (int)sizeof( tag ) - 1,
67
(int)sizeof( value ) - 1 );
69
while ( sscanf( cibp, format, tag, value ) == 2 ) {
72
tag[ sizeof( tag ) - 1 ] = '\0';
73
value[ sizeof( value ) - 1 ] = '\0';
75
/* remove trailing whitespaces */
76
p = tag + strlen( tag ) - 1;
77
/* remove trailing whitespaces */
78
while ( ( *p == ' ' || *p == '\t' ) && p > tag )
81
if ( strcmp( tag, "processor" ) == 0 ) {
82
if ( sscanf( value, "%d", &coreUniqueId ) == 1 ) {
83
if ( coreUniqueId >= HighNumCores ) {
84
/* Found a new processor core. Maybe even a new processor. (We'll check later) */
87
/* Each core has a clock speed. Allocate one per core found. */
88
Clocks = (float*) realloc( Clocks, (coreUniqueId+1) * sizeof( float ) );
89
memset(Clocks + HighNumCores, 0, (coreUniqueId +1 - HighNumCores) * sizeof( float ));
91
HighNumCores = coreUniqueId + 1;
93
snprintf( cmdName, sizeof( cmdName ) - 1, "cpu/cpu%d/clock", coreUniqueId );
94
registerMonitor( cmdName, "float", printCPUxClock, printCPUxClockInfo,
98
} else if ( strcmp( tag, "cpu MHz" ) == 0 ) {
99
if (HighNumCores > coreUniqueId) {
100
/* The if statement above *should* always be true, but there's no harm in being safe. */
101
sscanf( value, "%f", &Clocks[ coreUniqueId ] );
103
} else if ( strcmp( tag, "core id" ) == 0 ) {
104
/* the core id is per processor */
107
if ( (sscanf( value, "%d", &curCore ) == 1) && curCore == 0 ) {
108
/* core id is back at 0. We just found a new processor. */
111
if (numProcessors > HighNumProcessors)
112
HighNumProcessors = numProcessors;
115
/* Move cibp to beginning of next line, if there is one. */
116
cibp = strchr( cibp, '\n' );
120
cibp = CpuInfoBuf + strlen( CpuInfoBuf );
123
numCores = coreUniqueId + 1;
129
================================ public part =================================
132
void initCpuInfo( struct SensorModul* sm )
136
if ( updateCpuInfo() < 0 )
139
registerMonitor( "system/processors", "integer", printNumCpus, printNumCpusInfo,
141
registerMonitor( "system/cores", "integer", printNumCores, printNumCoresInfo,
146
registerMonitor( "cpu/system/AverageClock", "float", printCPUClock, printCPUClockInfo,
150
void exitCpuInfo( void )
157
int updateCpuInfo( void )
165
if ( ( fd = open( "/proc/cpuinfo", O_RDONLY ) ) < 0 ) {
166
if ( CpuInfoOK != 0 )
167
print_error( "Cannot open file \'/proc/cpuinfo\'!\n"
168
"The kernel needs to be compiled with support\n"
169
"for /proc file system enabled!\n" );
176
ssize_t len = read( fd, CpuInfoBuf + n, CPUINFOBUFSIZE - 1 - n );
178
print_error( "Failed to read file \'/proc/cpuinfo\'!\n" );
184
if( len == 0 ) /* reading finished */
186
if( n == CPUINFOBUFSIZE - 1 ) {
187
log_error( "Internal buffer too small to read \'/proc/cpuinfo\'" );
196
CpuInfoBuf[ n ] = '\0';
202
void printCPUxClock( const char* cmd )
209
sscanf( cmd + 7, "%d", &id );
210
output( "%f\n", Clocks[ id ] );
213
void printCPUClock( const char* cmd )
217
cmd = cmd; /*Silence warning*/
223
for ( id = 0; id < HighNumCores; id++ ) {
224
clock += Clocks[ id ];
226
clock /= HighNumCores;
227
output( "%f\n", clock );
230
void printCPUxClockInfo( const char* cmd )
234
sscanf( cmd + 7, "%d", &id );
235
output( "CPU%d Clock Frequency\t0\t0\tMHz\n", id );
238
void printCPUClockInfo( const char* cmd )
240
cmd = cmd; /*Silence warning*/
241
output( "CPU Clock Frequency\t0\t0\tMHz\n" );
244
void printNumCpus( const char* cmd )
251
output( "%d\n", numProcessors );
254
void printNumCpusInfo( const char* cmd )
258
output( "Number of physical CPUs\t0\t0\t\n" );
261
void printNumCores( const char* cmd )
268
output( "%d\n", numCores );
271
void printNumCoresInfo( const char* cmd )
275
output( "Total number of processor cores\t0\t0\t\n" );