00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "sfprocpidstats.h"
00029
00030 #ifdef LINUX_SMP
00031
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <linux/param.h>
00035 #include <sys/types.h>
00036 #include <string.h>
00037 #include <math.h>
00038
00039 #include "util.h"
00040
00041 #define PROC_STAT "/proc/stat"
00042 #define PROC_SELF_CPU "/proc/self/cpu"
00043 #define PROC_SELF_STAT "/proc/self/stat"
00044
00045 typedef struct _USERSYS {
00046 u_long user;
00047 u_long sys;
00048 u_long idle;
00049 } USERSYS;
00050
00051 static int giCPUs = 1;
00052
00053 static USERSYS *gpStatCPUs = NULL;
00054 static USERSYS *gpStatCPUs_2 = NULL;
00055
00056 static FILE *proc_stat;
00057
00058 static int GetProcStatCpu(USERSYS *pStatCPUs, int iCPUs)
00059 {
00060 int iRet;
00061 int iCtr;
00062 u_long ulUser;
00063 u_long ulNice;
00064 u_long ulSys;
00065 u_long ulIdle;
00066 char buf[256];
00067
00068 rewind(proc_stat);
00069
00070
00071
00072
00073
00074
00075 if(iCPUs != 1)
00076 {
00077 if(!fgets(buf, sizeof(buf), proc_stat))
00078 return -1;
00079 }
00080
00081
00082
00083
00084
00085 for(iCtr = 0; iCtr < iCPUs; iCtr++)
00086 {
00087 if(!fgets(buf, sizeof(buf), proc_stat))
00088 return -1;
00089
00090 iRet = sscanf(buf, "%*s %lu %lu %lu %lu",
00091 &ulUser, &ulNice, &ulSys, &ulIdle);
00092
00093 if(iRet == EOF || iRet < 4)
00094 return -1;
00095
00096 pStatCPUs[iCtr].user = ulUser + ulNice;
00097 pStatCPUs[iCtr].sys = ulSys;
00098 pStatCPUs[iCtr].idle = ulIdle;
00099 }
00100
00101 return 0;
00102 }
00103
00104 static int GetCpuNum()
00105 {
00106 int iRet;
00107 int iCPUs = 0;
00108 char acCpuName[10+1];
00109 char buf[256];
00110
00111 rewind(proc_stat);
00112
00113 while(1)
00114 {
00115 if(!fgets(buf, sizeof(buf), proc_stat))
00116 return 0;
00117
00118 iRet = sscanf(buf, "%10s %*u %*u %*u %*u", acCpuName);
00119 if(iRet < 1 || iRet == EOF)
00120 {
00121 return 0;
00122 }
00123
00124 acCpuName[sizeof(acCpuName)-1] = 0x00;
00125
00126 if(strncmp(acCpuName, "cpu", 3))
00127 {
00128 break;
00129 }
00130
00131 iCPUs++;
00132 }
00133
00134
00135
00136
00137
00138
00139 if(iCPUs > 1)
00140 iCPUs--;
00141
00142 return iCPUs;
00143 }
00144
00145 int sfInitProcPidStats(SFPROCPIDSTATS *sfProcPidStats)
00146 {
00147 proc_stat = fopen(PROC_STAT, "r");
00148 if(!proc_stat)
00149 {
00150 FatalError("PERFMONITOR ERROR: Can't open %s.", PROC_STAT);
00151 }
00152
00153 giCPUs = GetCpuNum();
00154 if(giCPUs <= 0)
00155 {
00156 FatalError("PERFMONITOR ERROR: Error reading CPUs from %s.",
00157 PROC_STAT);
00158 }
00159
00160 gpStatCPUs = (USERSYS *)calloc(giCPUs, sizeof(USERSYS));
00161 if(!gpStatCPUs)
00162 FatalError("PERFMONITOR ERROR: Error allocating CPU mem.");
00163
00164 gpStatCPUs_2 = (USERSYS *)calloc(giCPUs, sizeof(USERSYS));
00165 if(!gpStatCPUs_2)
00166 FatalError("PERFMONITOR ERROR: Error allocating CPU mem.");
00167
00168
00169
00170
00171 sfProcPidStats->SysCPUs = (CPUSTAT *)calloc(giCPUs, sizeof(CPUSTAT));
00172 if(!sfProcPidStats->SysCPUs)
00173 FatalError("PERFMONITOR ERROR: Error allocating SysCPU mem.");
00174
00175 sfProcPidStats->iCPUs = giCPUs;
00176
00177 if(GetProcStatCpu(gpStatCPUs, giCPUs))
00178 FatalError("PERFMONITOR ERROR: Error while reading '%s'.",
00179 PROC_STAT);
00180
00181 fclose(proc_stat);
00182
00183 return 0;
00184 }
00185
00186 int sfProcessProcPidStats(SFPROCPIDSTATS *sfProcPidStats)
00187 {
00188 static int iError = 0;
00189 int iCtr;
00190 u_long ulCPUjiffies;
00191
00192 proc_stat = fopen(PROC_STAT, "r");
00193 if(!proc_stat)
00194 {
00195 if(!iError)
00196 {
00197 ErrorMessage("PERFMONITOR ERROR: Cannot open %s.", PROC_STAT);
00198 iError = 1;
00199 }
00200
00201 return -1;
00202 }
00203
00204 if(GetProcStatCpu(gpStatCPUs_2, giCPUs))
00205 {
00206 if(!iError)
00207 {
00208 ErrorMessage("PERFMONITOR ERROR: Error while reading '%s'.",
00209 PROC_STAT);
00210 iError = 1;
00211 }
00212
00213 return -1;
00214 }
00215
00216 fclose(proc_stat);
00217
00218
00219
00220
00221 for(iCtr = 0; iCtr < giCPUs; iCtr++)
00222 {
00223 ulCPUjiffies = (gpStatCPUs_2[iCtr].user - gpStatCPUs[iCtr].user) +
00224 (gpStatCPUs_2[iCtr].sys - gpStatCPUs[iCtr].sys) +
00225 (gpStatCPUs_2[iCtr].idle - gpStatCPUs[iCtr].idle);
00226
00227 if(gpStatCPUs_2[iCtr].user > gpStatCPUs[iCtr].user)
00228 {
00229 sfProcPidStats->SysCPUs[iCtr].user = (((double)(gpStatCPUs_2[iCtr].user -
00230 gpStatCPUs[iCtr].user)) /
00231 ulCPUjiffies) * 100.0;
00232 if(sfProcPidStats->SysCPUs[iCtr].user < .01)
00233 {
00234 sfProcPidStats->SysCPUs[iCtr].user = 0;
00235 }
00236 }
00237 else
00238 {
00239 sfProcPidStats->SysCPUs[iCtr].user = 0;
00240 }
00241
00242 if(gpStatCPUs_2[iCtr].sys > gpStatCPUs[iCtr].sys)
00243 {
00244 sfProcPidStats->SysCPUs[iCtr].sys = (((double)(gpStatCPUs_2[iCtr].sys -
00245 gpStatCPUs[iCtr].sys)) /
00246 ulCPUjiffies) * 100.0;
00247 if(sfProcPidStats->SysCPUs[iCtr].sys < .01)
00248 {
00249 sfProcPidStats->SysCPUs[iCtr].sys = 0;
00250 }
00251 }
00252 else
00253 {
00254 sfProcPidStats->SysCPUs[iCtr].sys = 0;
00255 }
00256
00257 if(gpStatCPUs_2[iCtr].idle > gpStatCPUs[iCtr].idle)
00258 {
00259 sfProcPidStats->SysCPUs[iCtr].idle = (((double)(gpStatCPUs_2[iCtr].idle -
00260 gpStatCPUs[iCtr].idle)) /
00261 ulCPUjiffies) * 100.0;
00262 if(sfProcPidStats->SysCPUs[iCtr].idle < .01)
00263 {
00264 sfProcPidStats->SysCPUs[iCtr].idle = 0;
00265 }
00266 }
00267 else
00268 {
00269 sfProcPidStats->SysCPUs[iCtr].idle = 0;
00270 }
00271
00272
00273
00274
00275 gpStatCPUs[iCtr].user = gpStatCPUs_2[iCtr].user;
00276 gpStatCPUs[iCtr].sys = gpStatCPUs_2[iCtr].sys;
00277 gpStatCPUs[iCtr].idle = gpStatCPUs_2[iCtr].idle;
00278 }
00279
00280 return 0;
00281 }
00282
00283 #endif
00284