s3-libads: use ldap_init_fd() to initialize a ldap session if possible
[bbaumbach/samba-autobuild/.git] / examples / perfcounter / perf_writer_cpu.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Performance Counter Daemon
4  *
5  *  Copyright (C) Marcin Krzysztof Porwit    2005
6  *  
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 3 of the License, or
10  *  (at your option) any later version.
11  *  
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.
16  *  
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "perf.h"
22
23 void init_cpudata_desc(PERF_DATA_BLOCK *data)
24 {
25     init_perf_counter(&(data->cpuInfo.cpuObjDesc),
26                       &(data->cpuInfo.cpuObjDesc),
27                       get_counter_id(data),
28                       "Processor",
29                       "The Processor object consists of counters that describe the behavior of the CPU.",
30                       0,
31                       PERF_OBJECT);
32     init_perf_counter(&(data->cpuInfo.userCPU),
33                       &(data->cpuInfo.cpuObjDesc),
34                       get_counter_id(data),
35                       "\% User CPU Utilization",
36                       "\% User CPU Utilization is the percentage of the CPU used by  processes executing user code.",
37                       PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
38                       PERF_COUNTER);
39     init_perf_counter(&(data->cpuInfo.systemCPU),
40                       &(data->cpuInfo.cpuObjDesc),
41                       get_counter_id(data),
42                       "\% System CPU Utilization",
43                       "\% System CPU Utilization is the percentage of the CPU used by processes doing system calls.",
44                       PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
45                       PERF_COUNTER);
46     init_perf_counter(&(data->cpuInfo.niceCPU),
47                       &(data->cpuInfo.cpuObjDesc),
48                       get_counter_id(data),
49                       "\% Nice CPU Utilization",
50                       "\% Nice CPU Utilization is the percentage of the CPU used by processes running in nice mode.",
51                       PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW,
52                       PERF_COUNTER);
53     init_perf_counter(&(data->cpuInfo.idleCPU),
54                       &(data->cpuInfo.cpuObjDesc),
55                       get_counter_id(data),
56                       "\% Idle CPU",
57                       "\% Idle CPU is the percentage of the CPU not doing any work.",
58                       PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW,
59                       PERF_COUNTER);
60
61     return;
62 }
63
64 void get_cpuinfo(PERF_DATA_BLOCK *data)
65 {
66     int num, i;
67     unsigned int cpuid;
68     char buf[PROC_BUF];
69     static FILE *fp = NULL;
70
71     if(!fp)
72     {
73         if(!(fp = fopen("/proc/stat", "r")))
74         {
75             perror("get_cpuinfo: fopen");
76             exit(1);
77         }
78     }
79
80     rewind(fp);
81     fflush(fp);
82
83     /* Read in the first line and discard it -- that has the CPU summary */
84     if(!fgets(buf, sizeof(buf), fp))
85     {
86         perror("get_cpuinfo: fgets");
87         exit(1);
88     }
89     for(i = 0; i < data->cpuInfo.numCPUs; i++)
90     {
91         if(!fgets(buf, sizeof(buf), fp))
92         {
93             perror("get_cpuinfo: fgets");
94             exit(1);
95         }
96         num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu",
97                      &cpuid,
98                      &data->cpuInfo.data[i].user,
99                      &data->cpuInfo.data[i].nice,
100                      &data->cpuInfo.data[i].system,
101                      &data->cpuInfo.data[i].idle);
102         if(i != cpuid)
103         {
104             perror("get_cpuinfo: /proc/stat inconsistent?");
105             exit(1);
106         }
107         /*
108           Alternate way of doing things:
109           struct tms buffer;
110           data->PerfTime100nSec = times(&buffer);
111         */
112         data->PerfTime100nSec += data->cpuInfo.data[i].user +
113             data->cpuInfo.data[i].nice +
114             data->cpuInfo.data[i].system +
115             data->cpuInfo.data[i].idle;
116     }
117     data->PerfTime100nSec /= data->cpuInfo.numCPUs;
118     return;
119 }
120
121 void init_cpu_data(PERF_DATA_BLOCK *data)
122 {
123     data->cpuInfo.data = calloc(data->cpuInfo.numCPUs, sizeof(*data->cpuInfo.data));
124     if(!data->cpuInfo.data)
125     {
126         perror("init_cpu_data: out of memory");
127         exit(1);
128     }
129
130     init_cpudata_desc(data);
131
132     get_cpuinfo(data);
133
134     return;
135 }   
136
137 void output_cpu_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
138 {
139     output_perf_desc(data->cpuInfo.cpuObjDesc, rt);
140     output_perf_desc(data->cpuInfo.userCPU, rt);
141     output_perf_desc(data->cpuInfo.niceCPU, rt);
142     output_perf_desc(data->cpuInfo.systemCPU, rt);
143     output_perf_desc(data->cpuInfo.idleCPU, rt);
144     if(data->cpuInfo.numCPUs > 1)
145             output_num_instances(data->cpuInfo.cpuObjDesc, data->cpuInfo.numCPUs + 1, rt);
146
147     return;
148 }
149
150 void output_cpuinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
151 {
152     int i;
153     char buf[NAME_LEN];
154
155     output_perf_counter(data->cpuInfo.userCPU,
156                         data->cpuInfo.data[0].user,
157                         rt, tdb_flags);
158     output_perf_counter(data->cpuInfo.systemCPU,
159                         data->cpuInfo.data[0].system,
160                         rt, tdb_flags);
161     output_perf_counter(data->cpuInfo.niceCPU,
162                         data->cpuInfo.data[0].nice,
163                         rt, tdb_flags);
164     output_perf_counter(data->cpuInfo.idleCPU,
165                         data->cpuInfo.data[0].idle,
166                         rt, tdb_flags);
167     if(data->cpuInfo.numCPUs > 1)
168       {
169               for(i = 0; i < data->cpuInfo.numCPUs; i++)
170               {
171                       memset(buf, 0, NAME_LEN);
172                       sprintf(buf, "cpu%d", i);
173                       output_perf_instance(data->cpuInfo.cpuObjDesc.index,
174                                            i,
175                                            (void *)&(data->cpuInfo.data[i]),
176                                            sizeof(data->cpuInfo.data[i]),
177                                            buf, rt, tdb_flags);
178               }
179               
180               memset(buf, 0, NAME_LEN);
181               sprintf(buf, "_Total");
182               output_perf_instance(data->cpuInfo.cpuObjDesc.index,
183                                    i,
184                                    (void *)&(data->cpuInfo.data[i]),
185                                    sizeof(data->cpuInfo.data[i]),
186                                    buf, rt, tdb_flags);
187       }
188     return;
189 }