ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/cpu_stats.c
Revision: 1.25
Committed: Mon Nov 1 18:30:17 2004 UTC (19 years, 6 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_12, LIBSTATGRAB_0_11_1, LIBSTATGRAB_0_11
Changes since 1.24: +25 -2 lines
Log Message:
Merge in patch to provide support for HP-UX 11.11.

Contributed by Roy Keene - thanks Roy!

File Contents

# Content
1 /*
2 * i-scream libstatgrab
3 * http://www.i-scream.org
4 * Copyright (C) 2000-2004 i-scream
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * $Id: cpu_stats.c,v 1.24 2004/07/18 21:30:11 ats Exp $
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <time.h>
28 #include "statgrab.h"
29 #include "tools.h"
30 #ifdef SOLARIS
31 #include <kstat.h>
32 #include <sys/sysinfo.h>
33 #include <string.h>
34 #endif
35 #if defined(LINUX) || defined(CYGWIN)
36 #include <stdio.h>
37 #endif
38 #if defined(FREEBSD) || defined(DFBSD)
39 #include <sys/sysctl.h>
40 #include <sys/dkstat.h>
41 #endif
42 #ifdef NETBSD
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/sysctl.h>
46 #include <sys/sched.h>
47 #endif
48 #ifdef OPENBSD
49 #include <sys/param.h>
50 #include <sys/sysctl.h>
51 #include <sys/dkstat.h>
52 #endif
53 #ifdef HPUX
54 #include <sys/param.h>
55 #include <sys/pstat.h>
56 #include <sys/dk.h>
57 #endif
58
59 static sg_cpu_stats cpu_now;
60 static int cpu_now_uninit=1;
61
62 sg_cpu_stats *sg_get_cpu_stats(){
63
64 #ifdef HPUX
65 struct pst_dynamic pstat_dynamic;
66 int i;
67 #endif
68 #ifdef SOLARIS
69 kstat_ctl_t *kc;
70 kstat_t *ksp;
71 cpu_stat_t cs;
72 #endif
73 #if defined(LINUX) || defined(CYGWIN)
74 FILE *f;
75 #endif
76 #ifdef ALLBSD
77 #if defined(NETBSD) || defined(OPENBSD)
78 int mib[2];
79 #endif
80 #ifdef NETBSD
81 u_int64_t cp_time[CPUSTATES];
82 #else
83 long cp_time[CPUSTATES];
84 #endif
85 size_t size;
86 #endif
87
88 cpu_now.user=0;
89 /* Not stored in linux or freebsd */
90 cpu_now.iowait=0;
91 cpu_now.kernel=0;
92 cpu_now.idle=0;
93 /* Not stored in linux, freebsd, or hpux */
94 cpu_now.swap=0;
95 cpu_now.total=0;
96 /* Not stored in solaris */
97 cpu_now.nice=0;
98
99 #ifdef HPUX
100 if (pstat_getdynamic(&pstat_dynamic, sizeof(pstat_dynamic), 1, 0) == -1) {
101 sg_set_error_with_errno(SG_ERROR_PSTAT, "pstat_dynamic");
102 return NULL;
103 }
104 cpu_now.user = pstat_dynamic.psd_cpu_time[CP_USER];
105 cpu_now.iowait = pstat_dynamic.psd_cpu_time[CP_WAIT];
106 cpu_now.kernel = pstat_dynamic.psd_cpu_time[CP_SSYS] + pstat_dynamic.psd_cpu_time[CP_SYS];
107 cpu_now.idle = pstat_dynamic.psd_cpu_time[CP_IDLE];
108 cpu_now.nice = pstat_dynamic.psd_cpu_time[CP_NICE];
109 for (i = 0; i < PST_MAX_CPUSTATES; i++) {
110 cpu_now.total += pstat_dynamic.psd_cpu_time[i];
111 }
112 #endif
113 #ifdef SOLARIS
114 if ((kc = kstat_open()) == NULL) {
115 sg_set_error(SG_ERROR_KSTAT_OPEN, NULL);
116 return NULL;
117 }
118 for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) {
119 if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue;
120 if (kstat_read(kc, ksp, &cs) == -1) {
121 continue;
122 }
123 cpu_now.user+=(long long)cs.cpu_sysinfo.cpu[CPU_USER];
124 cpu_now.iowait+=(long long)cs.cpu_sysinfo.cpu[CPU_WAIT];
125 cpu_now.kernel+=(long long)cs.cpu_sysinfo.cpu[CPU_KERNEL];
126 cpu_now.idle+=(long long)cs.cpu_sysinfo.cpu[CPU_IDLE];
127 cpu_now.swap+=(long long)cs.cpu_sysinfo.cpu[CPU_STATES];
128 }
129
130 cpu_now.total=cpu_now.user+cpu_now.iowait+cpu_now.kernel+cpu_now.idle+cpu_now.swap;
131
132 kstat_close(kc);
133 #endif
134 #if defined(LINUX) || defined(CYGWIN)
135 if ((f=fopen("/proc/stat", "r" ))==NULL) {
136 sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/stat");
137 return NULL;
138 }
139 /* The very first line should be cpu */
140 if((fscanf(f, "cpu %lld %lld %lld %lld", \
141 &cpu_now.user, \
142 &cpu_now.nice, \
143 &cpu_now.kernel, \
144 &cpu_now.idle)) != 4){
145 sg_set_error(SG_ERROR_PARSE, "cpu");
146 fclose(f);
147 return NULL;
148 }
149
150 fclose(f);
151
152 cpu_now.total=cpu_now.user+cpu_now.nice+cpu_now.kernel+cpu_now.idle;
153 #endif
154 #ifdef ALLBSD
155 #if defined(FREEBSD) || defined(DFBSD)
156 size = sizeof cp_time;
157 if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) < 0){
158 sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "kern.cp_time");
159 return NULL;
160 }
161 #else
162 mib[0] = CTL_KERN;
163 #ifdef NETBSD
164 mib[1] = KERN_CP_TIME;
165 #else
166 mib[1] = KERN_CPTIME;
167 #endif
168 size = sizeof cp_time;
169 if (sysctl(mib, 2, &cp_time, &size, NULL, 0) < 0) {
170 #ifdef NETBSD
171 sg_set_error_with_errno(SG_ERROR_SYSCTL,
172 "CTL_KERN.KERN_CP_TIME");
173 #else
174 sg_set_error_with_errno(SG_ERROR_SYSCTL,
175 "CTL_KERN.KERN_CPTIME");
176 #endif
177 return NULL;
178 }
179 #endif
180
181 cpu_now.user=cp_time[CP_USER];
182 cpu_now.nice=cp_time[CP_NICE];
183 cpu_now.kernel=cp_time[CP_SYS];
184 cpu_now.idle=cp_time[CP_IDLE];
185
186 cpu_now.total=cpu_now.user+cpu_now.nice+cpu_now.kernel+cpu_now.idle;
187
188 #endif
189
190 cpu_now.systime=time(NULL);
191 cpu_now_uninit=0;
192
193
194 return &cpu_now;
195 }
196
197 sg_cpu_stats *sg_get_cpu_stats_diff(){
198 static sg_cpu_stats cpu_diff;
199 sg_cpu_stats cpu_then, *cpu_tmp;
200
201 if (cpu_now_uninit){
202 if((cpu_tmp=sg_get_cpu_stats())==NULL){
203 /* Should sg_get_cpu_stats fail */
204 return NULL;
205 }
206 return cpu_tmp;
207 }
208
209
210 cpu_then.user=cpu_now.user;
211 cpu_then.kernel=cpu_now.kernel;
212 cpu_then.idle=cpu_now.idle;
213 cpu_then.iowait=cpu_now.iowait;
214 cpu_then.swap=cpu_now.swap;
215 cpu_then.nice=cpu_now.nice;
216 cpu_then.total=cpu_now.total;
217 cpu_then.systime=cpu_now.systime;
218
219 if((cpu_tmp=sg_get_cpu_stats())==NULL){
220 return NULL;
221 }
222
223 cpu_diff.user = cpu_now.user - cpu_then.user;
224 cpu_diff.kernel = cpu_now.kernel - cpu_then.kernel;
225 cpu_diff.idle = cpu_now.idle - cpu_then.idle;
226 cpu_diff.iowait = cpu_now.iowait - cpu_then.iowait;
227 cpu_diff.swap = cpu_now.swap - cpu_then.swap;
228 cpu_diff.nice = cpu_now.nice - cpu_then.nice;
229 cpu_diff.total = cpu_now.total - cpu_then.total;
230 cpu_diff.systime = cpu_now.systime - cpu_then.systime;
231
232 return &cpu_diff;
233 }
234
235 sg_cpu_percents *sg_get_cpu_percents(){
236 static sg_cpu_percents cpu_usage;
237 sg_cpu_stats *cs_ptr;
238
239 cs_ptr=sg_get_cpu_stats_diff();
240 if(cs_ptr==NULL){
241 return NULL;
242 }
243
244 cpu_usage.user = ((float)cs_ptr->user / (float)cs_ptr->total)*100;
245 cpu_usage.kernel = ((float)cs_ptr->kernel / (float)cs_ptr->total)*100;
246 cpu_usage.idle = ((float)cs_ptr->idle / (float)cs_ptr->total)*100;
247 cpu_usage.iowait = ((float)cs_ptr->iowait / (float)cs_ptr->total)*100;
248 cpu_usage.swap = ((float)cs_ptr->swap / (float)cs_ptr->total)*100;
249 cpu_usage.nice = ((float)cs_ptr->nice / (float)cs_ptr->total)*100;
250 cpu_usage.time_taken = cs_ptr->systime;
251
252 return &cpu_usage;
253
254 }
255