2 KSysGuard, the KDE System Guard
4 Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
6 Irix support by Carsten Kroll <ckroll@pinnaclesys.com>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 #include <sys/types.h>
28 #include <sys/sysmp.h>
29 #include <sys/sysinfo.h>
33 #include "ksysguardd.h"
37 long percentages(int cnt
, int *out
, long *new, long *old
, long *diffs
);
42 long cp_time
[CPUSTATES
];
43 long cp_old
[CPUSTATES
];
44 long cp_diff
[CPUSTATES
];
45 int cpu_states
[CPUSTATES
];
48 long cp_time
[CPUSTATES
];
49 long cp_old
[CPUSTATES
];
50 long cp_diff
[CPUSTATES
];
51 int cpu_states
[CPUSTATES
];
54 static struct cpu_info
*g_ci
;
56 /* returns the requested cpu number starting at 0*/
57 int getID(const char *cmd
){
59 sscanf(cmd
+ 7, "%d", &id
);
64 initCpuInfo(struct SensorModul
* sm
)
68 if (sysmp(MP_NPROCS
,&nCPUs
) < 0) nCPUs
=0;
70 g_ci
= malloc(sizeof(struct cpu_info
) * nCPUs
);
71 memset(g_ci
,0,sizeof(struct cpu_info
) * nCPUs
);
73 registerMonitor("cpu/system/user", "integer", printCPUUser
, printCPUUserInfo
, sm
);
74 registerMonitor("cpu/system/sys", "integer", printCPUSys
, printCPUSysInfo
, sm
);
75 registerMonitor("cpu/system/idle", "integer", printCPUIdle
, printCPUIdleInfo
, sm
);
77 /* Monitor names changed from kde3 => kde4. Remain compatible with legacy requests when possible. */
78 registerLegacyMonitor("cpu/user", "integer", printCPUUser
, printCPUUserInfo
, sm
);
79 registerLegacyMonitor("cpu/sys", "integer", printCPUSys
, printCPUSysInfo
, sm
);
80 registerLegacyMonitor("cpu/idle", "integer", printCPUIdle
, printCPUIdleInfo
, sm
);
82 if (nCPUs
> 1) for (i
=0;i
<nCPUs
;i
++){
83 /* indidividual CPU load */
84 sprintf(mname
,"cpu/cpu%d/user",i
+1);
85 registerMonitor(mname
, "integer", printCPUxUser
,
86 printCPUUserInfo
, sm
);
87 sprintf(mname
,"cpu/cpu%d/sys",i
+1);
88 registerMonitor(mname
, "integer", printCPUxSys
,
90 sprintf(mname
,"cpu/cpu%d/idle",i
+1);
91 registerMonitor(mname
, "integer", printCPUxIdle
,
92 printCPUIdleInfo
, sm
);
101 removeMonitor("cpu/system/user");
102 removeMonitor("cpu/system/nice");
103 removeMonitor("cpu/system/sys");
104 removeMonitor("cpu/system/idle");
106 /* Todo: Dynamically registered monitors (per cpu, per disk) are not removed yet) */
108 /* These were registered as legacy monitors */
109 removeMonitor("cpu/user");
110 removeMonitor("cpu/nice");
111 removeMonitor("cpu/sys");
112 removeMonitor("cpu/idle");
124 /* overall summary */
125 if (sysmp(MP_SAGET
,MPSA_SINFO
,&si
,sizeof(struct sysinfo
)) >=0){
126 cp_time
[CPU_IDLE
] =si
.cpu
[CPU_IDLE
];
127 cp_time
[CPU_USER
] =si
.cpu
[CPU_USER
];
128 cp_time
[CPU_KERNEL
]=si
.cpu
[CPU_KERNEL
];
129 cp_time
[CPU_SXBRK
] =si
.cpu
[CPU_SXBRK
];
130 cp_time
[CPU_INTR
] =si
.cpu
[CPU_INTR
];
131 cp_time
[CPU_WAIT
] =si
.cpu
[CPU_WAIT
];
132 percentages(CPUSTATES
,cpu_states
,cp_time
,cp_old
,cp_diff
);
134 /* individual CPU statistics*/
135 if (nCPUs
> 1) for (i
=0;i
<nCPUs
;i
++){
136 if (sysmp(MP_SAGET1
,MPSA_SINFO
,&si
,sizeof(struct sysinfo
),i
) >=0){
137 g_ci
[i
].cp_time
[CPU_IDLE
] =si
.cpu
[CPU_IDLE
];
138 g_ci
[i
].cp_time
[CPU_USER
] =si
.cpu
[CPU_USER
];
139 g_ci
[i
].cp_time
[CPU_KERNEL
]=si
.cpu
[CPU_KERNEL
];
140 g_ci
[i
].cp_time
[CPU_SXBRK
] =si
.cpu
[CPU_SXBRK
];
141 g_ci
[i
].cp_time
[CPU_INTR
] =si
.cpu
[CPU_INTR
];
142 g_ci
[i
].cp_time
[CPU_WAIT
] =si
.cpu
[CPU_WAIT
];
143 percentages(CPUSTATES
, g_ci
[i
].cpu_states
, g_ci
[i
].cp_time
, g_ci
[i
].cp_old
,g_ci
[i
].cp_diff
);
152 printCPUUser(const char* cmd
)
154 fprintf(CurrentClient
, "%d\n", cpu_states
[CPU_USER
]/10);
158 printCPUUserInfo(const char* cmd
)
160 fprintf(CurrentClient
, "CPU User Load\t0\t100\t%%\n");
164 printCPUSys(const char* cmd
)
166 fprintf(CurrentClient
, "%d\n", cpu_states
[CPU_KERNEL
]/10);
170 printCPUSysInfo(const char* cmd
)
172 fprintf(CurrentClient
, "CPU System Load\t0\t100\t%%\n");
176 printCPUIdle(const char* cmd
)
178 fprintf(CurrentClient
, "%d\n", cpu_states
[CPU_IDLE
]/10);
182 printCPUIdleInfo(const char* cmd
)
184 fprintf(CurrentClient
, "CPU Idle Load\t0\t100\t%%\n");
186 /* same as above but for individual CPUs */
188 printCPUxUser(const char* cmd
)
190 fprintf(CurrentClient
, "%d\n", g_ci
[getID(cmd
)].cpu_states
[CPU_USER
]/10);
194 printCPUxSys(const char* cmd
)
196 fprintf(CurrentClient
, "%d\n", g_ci
[getID(cmd
)].cpu_states
[CPU_KERNEL
]/10);
200 printCPUxIdle(const char* cmd
)
202 fprintf(CurrentClient
, "%d\n", g_ci
[getID(cmd
)].cpu_states
[CPU_IDLE
]/10);
206 /* The part ripped from top... */
208 * Top users/processes display for Unix
211 * This program may be freely redistributed,
212 * but this entire comment MUST remain intact.
214 * Copyright (c) 1984, 1989, William LeFebvre, Rice University
215 * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
219 * percentages(cnt, out, new, old, diffs) - calculate percentage change
220 * between array "old" and "new", putting the percentages in "out".
221 * "cnt" is size of each array and "diffs" is used for scratch space.
222 * The array "old" is updated on each call.
223 * The routine assumes modulo arithmetic. This function is especially
224 * useful on BSD mchines for calculating cpu state percentages.
227 long percentages(cnt
, out
, new, old
, diffs
)
237 register long change
;
238 register long total_change
;
246 /* calculate changes for each state and the overall change */
247 for (i
= 0; i
< cnt
; i
++)
249 if ((change
= *new - *old
) < 0)
251 /* this only happens when the counter wraps */
253 ((unsigned long)*new-(unsigned long)*old
);
255 total_change
+= (*dp
++ = change
);
259 /* avoid divide by zero potential */
260 if (total_change
== 0)
265 /* calculate percentages based on overall change, rounding up */
266 half_total
= total_change
/ 2l;
268 /* Do not divide by 0. Causes Floating point exception */
270 for (i
= 0; i
< cnt
; i
++)
272 *out
++ = (int)((*diffs
++ * 1000 + half_total
) / total_change
);
276 /* return the total in case the caller wants to use it */
277 return(total_change
);