ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/cpu_stats.c
Revision: 1.18
Committed: Thu Feb 12 23:04:52 2004 UTC (20 years, 3 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.17: +10 -1 lines
Log Message:
Add preliminary support for OpenBSD (tested on 3.3).

All works apart from Disk IO stats - currently the disks are not named
correctly. The fix for this is probably to use KVM.

Mostly similar to the NetBSD code, the notable exception being the uvm
stuff. In NetBSD there's a function to get it, in OpenBSD sysctl is needed
to get hold of it.

File Contents

# Content
1 /*
2 * i-scream central monitoring system
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.17 2004/01/19 16:49:21 tdb Exp $
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <time.h>
28 #include "statgrab.h"
29 #ifdef SOLARIS
30 #include <kstat.h>
31 #include <sys/sysinfo.h>
32 #include <string.h>
33 #endif
34 #if defined(LINUX) || defined(CYGWIN)
35 #include <stdio.h>
36 #endif
37 #ifdef FREEBSD
38 #include <sys/sysctl.h>
39 #include <sys/dkstat.h>
40 #endif
41 #ifdef NETBSD
42 #include <sys/types.h>
43 #include <sys/param.h>
44 #include <sys/sysctl.h>
45 #include <sys/sched.h>
46 #endif
47 #ifdef OPENBSD
48 #include <sys/param.h>
49 #include <sys/sysctl.h>
50 #include <sys/dkstat.h>
51 #endif
52
53 static cpu_states_t cpu_now;
54 static int cpu_now_uninit=1;
55
56 cpu_states_t *get_cpu_totals(){
57
58 #ifdef SOLARIS
59 kstat_ctl_t *kc;
60 kstat_t *ksp;
61 cpu_stat_t cs;
62 #endif
63 #if defined(LINUX) || defined(CYGWIN)
64 FILE *f;
65 #endif
66 #ifdef ALLBSD
67 #ifndef FREEBSD
68 int mib[2];
69 #endif
70 #ifdef NETBSD
71 u_int64_t cp_time[CPUSTATES];
72 #else
73 long cp_time[CPUSTATES];
74 #endif
75 size_t size;
76 #endif
77
78 cpu_now.user=0;
79 /* Not stored in linux or freebsd */
80 cpu_now.iowait=0;
81 cpu_now.kernel=0;
82 cpu_now.idle=0;
83 /* Not stored in linux or freebsd */
84 cpu_now.swap=0;
85 cpu_now.total=0;
86 /* Not stored in solaris */
87 cpu_now.nice=0;
88
89 #ifdef SOLARIS
90 if ((kc = kstat_open()) == NULL) {
91 return NULL;
92 }
93 for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) {
94 if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue;
95 if (kstat_read(kc, ksp, &cs) == -1) {
96 continue;
97 }
98 cpu_now.user+=(long long)cs.cpu_sysinfo.cpu[CPU_USER];
99 cpu_now.iowait+=(long long)cs.cpu_sysinfo.cpu[CPU_WAIT];
100 cpu_now.kernel+=(long long)cs.cpu_sysinfo.cpu[CPU_KERNEL];
101 cpu_now.idle+=(long long)cs.cpu_sysinfo.cpu[CPU_IDLE];
102 cpu_now.swap+=(long long)cs.cpu_sysinfo.cpu[CPU_STATES];
103 }
104
105 cpu_now.total=cpu_now.user+cpu_now.iowait+cpu_now.kernel+cpu_now.idle+cpu_now.swap;
106
107 kstat_close(kc);
108 #endif
109 #if defined(LINUX) || defined(CYGWIN)
110 if ((f=fopen("/proc/stat", "r" ))==NULL) {
111 return NULL;
112 }
113 /* The very first line should be cpu */
114 if((fscanf(f, "cpu %lld %lld %lld %lld", \
115 &cpu_now.user, \
116 &cpu_now.nice, \
117 &cpu_now.kernel, \
118 &cpu_now.idle)) != 4){
119 fclose(f);
120 return NULL;
121 }
122
123 fclose(f);
124
125 cpu_now.total=cpu_now.user+cpu_now.nice+cpu_now.kernel+cpu_now.idle;
126 #endif
127 #ifdef ALLBSD
128 #ifdef FREEBSD
129 size = sizeof cp_time;
130 if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) < 0){
131 return NULL;
132 }
133 #else
134 mib[0] = CTL_KERN;
135 #ifdef NETBSD
136 mib[1] = KERN_CP_TIME;
137 #else
138 mib[1] = KERN_CPTIME;
139 #endif
140 size = sizeof cp_time;
141 if (sysctl(mib, 2, &cp_time, &size, NULL, 0) < 0) {
142 return NULL;
143 }
144 #endif
145
146 cpu_now.user=cp_time[CP_USER];
147 cpu_now.nice=cp_time[CP_NICE];
148 cpu_now.kernel=cp_time[CP_SYS];
149 cpu_now.idle=cp_time[CP_IDLE];
150
151 cpu_now.total=cpu_now.user+cpu_now.nice+cpu_now.kernel+cpu_now.idle;
152
153 #endif
154
155 cpu_now.systime=time(NULL);
156 cpu_now_uninit=0;
157
158
159 return &cpu_now;
160 }
161
162 cpu_states_t *get_cpu_diff(){
163 static cpu_states_t cpu_diff;
164 cpu_states_t cpu_then, *cpu_tmp;
165
166 if (cpu_now_uninit){
167 if((cpu_tmp=get_cpu_totals())==NULL){
168 /* Should get_cpu_totals fail */
169 return NULL;
170 }
171 return cpu_tmp;
172 }
173
174
175 cpu_then.user=cpu_now.user;
176 cpu_then.kernel=cpu_now.kernel;
177 cpu_then.idle=cpu_now.idle;
178 cpu_then.iowait=cpu_now.iowait;
179 cpu_then.swap=cpu_now.swap;
180 cpu_then.nice=cpu_now.nice;
181 cpu_then.total=cpu_now.total;
182 cpu_then.systime=cpu_now.systime;
183
184 if((cpu_tmp=get_cpu_totals())==NULL){
185 return NULL;
186 }
187
188 cpu_diff.user = cpu_now.user - cpu_then.user;
189 cpu_diff.kernel = cpu_now.kernel - cpu_then.kernel;
190 cpu_diff.idle = cpu_now.idle - cpu_then.idle;
191 cpu_diff.iowait = cpu_now.iowait - cpu_then.iowait;
192 cpu_diff.swap = cpu_now.swap - cpu_then.swap;
193 cpu_diff.nice = cpu_now.nice - cpu_then.nice;
194 cpu_diff.total = cpu_now.total - cpu_then.total;
195 cpu_diff.systime = cpu_now.systime - cpu_then.systime;
196
197 return &cpu_diff;
198 }
199
200 cpu_percent_t *cpu_percent_usage(){
201 static cpu_percent_t cpu_usage;
202 cpu_states_t *cs_ptr;
203
204 cs_ptr=get_cpu_diff();
205 if(cs_ptr==NULL){
206 return NULL;
207 }
208
209 cpu_usage.user = ((float)cs_ptr->user / (float)cs_ptr->total)*100;
210 cpu_usage.kernel = ((float)cs_ptr->kernel / (float)cs_ptr->total)*100;
211 cpu_usage.idle = ((float)cs_ptr->idle / (float)cs_ptr->total)*100;
212 cpu_usage.iowait = ((float)cs_ptr->iowait / (float)cs_ptr->total)*100;
213 cpu_usage.swap = ((float)cs_ptr->swap / (float)cs_ptr->total)*100;
214 cpu_usage.nice = ((float)cs_ptr->nice / (float)cs_ptr->total)*100;
215 cpu_usage.time_taken = cs_ptr->systime;
216
217 return &cpu_usage;
218
219 }
220