2 * Unix SMB/CIFS implementation.
3 * Performance Counter Daemon
5 * Copyright (C) Marcin Krzysztof Porwit 2005
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 void init_cpudata_desc(PERF_DATA_BLOCK
*data
)
26 init_perf_counter(&(data
->cpuInfo
.cpuObjDesc
),
27 &(data
->cpuInfo
.cpuObjDesc
),
30 "The Processor object consists of counters that describe the behavior of the CPU.",
33 init_perf_counter(&(data
->cpuInfo
.userCPU
),
34 &(data
->cpuInfo
.cpuObjDesc
),
36 "\% User CPU Utilization",
37 "\% User CPU Utilization is the percentage of the CPU used by processes executing user code.",
38 PERF_SIZE_LARGE
| PERF_TYPE_COUNTER
| PERF_COUNTER_RATE
| PERF_TIMER_100NS
| PERF_DELTA_COUNTER
| PERF_DISPLAY_PERCENT
,
40 init_perf_counter(&(data
->cpuInfo
.systemCPU
),
41 &(data
->cpuInfo
.cpuObjDesc
),
43 "\% System CPU Utilization",
44 "\% System CPU Utilization is the percentage of the CPU used by processes doing system calls.",
45 PERF_SIZE_LARGE
| PERF_TYPE_COUNTER
| PERF_COUNTER_RATE
| PERF_TIMER_100NS
| PERF_DELTA_COUNTER
| PERF_DISPLAY_PERCENT
,
47 init_perf_counter(&(data
->cpuInfo
.niceCPU
),
48 &(data
->cpuInfo
.cpuObjDesc
),
50 "\% Nice CPU Utilization",
51 "\% Nice CPU Utilization is the percentage of the CPU used by processes running in nice mode.",
52 PERF_SIZE_LARGE
| PERF_TYPE_COUNTER
| PERF_COUNTER_RATE
| PERF_TIMER_100NS
| PERF_DELTA_COUNTER
| PERF_DISPLAY_NOSHOW
,
54 init_perf_counter(&(data
->cpuInfo
.idleCPU
),
55 &(data
->cpuInfo
.cpuObjDesc
),
58 "\% Idle CPU is the percentage of the CPU not doing any work.",
59 PERF_SIZE_LARGE
| PERF_TYPE_COUNTER
| PERF_COUNTER_RATE
| PERF_TIMER_100NS
| PERF_DELTA_COUNTER
| PERF_DISPLAY_NOSHOW
,
65 void get_cpuinfo(PERF_DATA_BLOCK
*data
)
70 static FILE *fp
= NULL
;
74 if(!(fp
= fopen("/proc/stat", "r")))
76 perror("get_cpuinfo: fopen");
84 /* Read in the first line and discard it -- that has the CPU summary */
85 if(!fgets(buf
, sizeof(buf
), fp
))
87 perror("get_cpuinfo: fgets");
90 for(i
= 0; i
< data
->cpuInfo
.numCPUs
; i
++)
92 if(!fgets(buf
, sizeof(buf
), fp
))
94 perror("get_cpuinfo: fgets");
97 num
= sscanf(buf
, "cpu%u %Lu %Lu %Lu %Lu",
99 &data
->cpuInfo
.data
[i
].user
,
100 &data
->cpuInfo
.data
[i
].nice
,
101 &data
->cpuInfo
.data
[i
].system
,
102 &data
->cpuInfo
.data
[i
].idle
);
105 perror("get_cpuinfo: /proc/stat inconsistent?");
109 Alternate way of doing things:
111 data->PerfTime100nSec = times(&buffer);
113 data
->PerfTime100nSec
+= data
->cpuInfo
.data
[i
].user
+
114 data
->cpuInfo
.data
[i
].nice
+
115 data
->cpuInfo
.data
[i
].system
+
116 data
->cpuInfo
.data
[i
].idle
;
118 data
->PerfTime100nSec
/= data
->cpuInfo
.numCPUs
;
122 void init_cpu_data(PERF_DATA_BLOCK
*data
)
124 data
->cpuInfo
.data
= calloc(data
->cpuInfo
.numCPUs
, sizeof(*data
->cpuInfo
.data
));
125 if(!data
->cpuInfo
.data
)
127 perror("init_cpu_data: out of memory");
131 init_cpudata_desc(data
);
138 void output_cpu_desc(PERF_DATA_BLOCK
*data
, RuntimeSettings rt
)
140 output_perf_desc(data
->cpuInfo
.cpuObjDesc
, rt
);
141 output_perf_desc(data
->cpuInfo
.userCPU
, rt
);
142 output_perf_desc(data
->cpuInfo
.niceCPU
, rt
);
143 output_perf_desc(data
->cpuInfo
.systemCPU
, rt
);
144 output_perf_desc(data
->cpuInfo
.idleCPU
, rt
);
145 if(data
->cpuInfo
.numCPUs
> 1)
146 output_num_instances(data
->cpuInfo
.cpuObjDesc
, data
->cpuInfo
.numCPUs
+ 1, rt
);
151 void output_cpuinfo(PERF_DATA_BLOCK
*data
, RuntimeSettings rt
, int tdb_flags
)
156 output_perf_counter(data
->cpuInfo
.userCPU
,
157 data
->cpuInfo
.data
[0].user
,
159 output_perf_counter(data
->cpuInfo
.systemCPU
,
160 data
->cpuInfo
.data
[0].system
,
162 output_perf_counter(data
->cpuInfo
.niceCPU
,
163 data
->cpuInfo
.data
[0].nice
,
165 output_perf_counter(data
->cpuInfo
.idleCPU
,
166 data
->cpuInfo
.data
[0].idle
,
168 if(data
->cpuInfo
.numCPUs
> 1)
170 for(i
= 0; i
< data
->cpuInfo
.numCPUs
; i
++)
172 memset(buf
, 0, NAME_LEN
);
173 sprintf(buf
, "cpu%d", i
);
174 output_perf_instance(data
->cpuInfo
.cpuObjDesc
.index
,
176 (void *)&(data
->cpuInfo
.data
[i
]),
177 sizeof(data
->cpuInfo
.data
[i
]),
181 memset(buf
, 0, NAME_LEN
);
182 sprintf(buf
, "_Total");
183 output_perf_instance(data
->cpuInfo
.cpuObjDesc
.index
,
185 (void *)&(data
->cpuInfo
.data
[i
]),
186 sizeof(data
->cpuInfo
.data
[i
]),