ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/cpu_stats.c
Revision: 1.13
Committed: Sun Oct 19 02:03:02 2003 UTC (20 years, 7 months ago) by ats
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_7
Changes since 1.12: +23 -1 lines
Log Message:
Initial support for NetBSD. This adds NetBSD support for everything
except diskio stats (since they're even more disturbingly complex to get
at on NetBSD than the three OSs we already support). Tested against
NetBSD 1.6 on i386.

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org
4 * Copyright (C) 2000-2003 i-scream
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <time.h>
26 #include "statgrab.h"
27 #ifdef SOLARIS
28 #include <kstat.h>
29 #include <sys/sysinfo.h>
30 #include <string.h>
31 #endif
32 #ifdef LINUX
33 #include <stdio.h>
34 #endif
35 #ifdef FREEBSD
36 #include <sys/sysctl.h>
37 #include <sys/dkstat.h>
38 #endif
39 #ifdef NETBSD
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <sys/sysctl.h>
43 #include <sys/sched.h>
44 #endif
45
46 static cpu_states_t cpu_now;
47 static int cpu_now_uninit=1;
48
49 cpu_states_t *get_cpu_totals(){
50
51 #ifdef SOLARIS
52 kstat_ctl_t *kc;
53 kstat_t *ksp;
54 cpu_stat_t cs;
55 #endif
56 #ifdef LINUX
57 FILE *f;
58 #endif
59 #ifdef ALLBSD
60 #ifndef FREEBSD
61 int mib[2];
62 #endif
63 #ifdef NETBSD
64 u_int64_t cp_time[CPUSTATES];
65 #else
66 long cp_time[CPUSTATES];
67 #endif
68 size_t size;
69 #endif
70
71 cpu_now.user=0;
72 /* Not stored in linux or freebsd */
73 cpu_now.iowait=0;
74 cpu_now.kernel=0;
75 cpu_now.idle=0;
76 /* Not stored in linux or freebsd */
77 cpu_now.swap=0;
78 cpu_now.total=0;
79 /* Not stored in solaris */
80 cpu_now.nice=0;
81
82 #ifdef SOLARIS
83 if ((kc = kstat_open()) == NULL) {
84 return NULL;
85 }
86 for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) {
87 if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue;
88 if (kstat_read(kc, ksp, &cs) == -1) {
89 continue;
90 }
91 cpu_now.user+=(long long)cs.cpu_sysinfo.cpu[CPU_USER];
92 cpu_now.iowait+=(long long)cs.cpu_sysinfo.cpu[CPU_WAIT];
93 cpu_now.kernel+=(long long)cs.cpu_sysinfo.cpu[CPU_KERNEL];
94 cpu_now.idle+=(long long)cs.cpu_sysinfo.cpu[CPU_IDLE];
95 cpu_now.swap+=(long long)cs.cpu_sysinfo.cpu[CPU_STATES];
96 }
97
98 cpu_now.total=cpu_now.user+cpu_now.iowait+cpu_now.kernel+cpu_now.idle+cpu_now.swap;
99
100 kstat_close(kc);
101 #endif
102 #ifdef LINUX
103 if ((f=fopen("/proc/stat", "r" ))==NULL) {
104 return NULL;
105 }
106 /* The very first line should be cpu */
107 if((fscanf(f, "cpu %lld %lld %lld %lld", \
108 &cpu_now.user, \
109 &cpu_now.nice, \
110 &cpu_now.kernel, \
111 &cpu_now.idle)) != 4){
112 fclose(f);
113 return NULL;
114 }
115
116 fclose(f);
117
118 cpu_now.total=cpu_now.user+cpu_now.nice+cpu_now.kernel+cpu_now.idle;
119 #endif
120 #ifdef ALLBSD
121 #ifdef FREEBSD
122 size = sizeof cp_time;
123 if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) < 0){
124 return NULL;
125 }
126 #else
127 mib[0] = CTL_KERN;
128 mib[1] = KERN_CP_TIME;
129 size = sizeof cp_time;
130 if (sysctl(mib, 2, &cp_time, &size, NULL, 0) < 0) {
131 return NULL;
132 }
133 #endif
134
135 cpu_now.user=cp_time[CP_USER];
136 cpu_now.nice=cp_time[CP_NICE];
137 cpu_now.kernel=cp_time[CP_SYS];
138 cpu_now.idle=cp_time[CP_IDLE];
139
140 cpu_now.total=cpu_now.user+cpu_now.nice+cpu_now.kernel+cpu_now.idle;
141
142 #endif
143
144 cpu_now.systime=time(NULL);
145 cpu_now_uninit=0;
146
147
148 return &cpu_now;
149 }
150
151 cpu_states_t *get_cpu_diff(){
152 static cpu_states_t cpu_diff;
153 cpu_states_t cpu_then, *cpu_tmp;
154
155 if (cpu_now_uninit){
156 if((cpu_tmp=get_cpu_totals())==NULL){
157 /* Should get_cpu_totals fail */
158 return NULL;
159 }
160 return cpu_tmp;
161 }
162
163
164 cpu_then.user=cpu_now.user;
165 cpu_then.kernel=cpu_now.kernel;
166 cpu_then.idle=cpu_now.idle;
167 cpu_then.iowait=cpu_now.iowait;
168 cpu_then.swap=cpu_now.swap;
169 cpu_then.nice=cpu_now.nice;
170 cpu_then.total=cpu_now.total;
171 cpu_then.systime=cpu_now.systime;
172
173 if((cpu_tmp=get_cpu_totals())==NULL){
174 return NULL;
175 }
176
177 cpu_diff.user = cpu_now.user - cpu_then.user;
178 cpu_diff.kernel = cpu_now.kernel - cpu_then.kernel;
179 cpu_diff.idle = cpu_now.idle - cpu_then.idle;
180 cpu_diff.iowait = cpu_now.iowait - cpu_then.iowait;
181 cpu_diff.swap = cpu_now.swap - cpu_then.swap;
182 cpu_diff.nice = cpu_now.nice - cpu_then.nice;
183 cpu_diff.total = cpu_now.total - cpu_then.total;
184 cpu_diff.systime = cpu_now.systime - cpu_then.systime;
185
186 return &cpu_diff;
187 }
188
189 cpu_percent_t *cpu_percent_usage(){
190 static cpu_percent_t cpu_usage;
191 cpu_states_t *cs_ptr;
192
193 cs_ptr=get_cpu_diff();
194 if(cs_ptr==NULL){
195 return NULL;
196 }
197
198 cpu_usage.user = ((float)cs_ptr->user / (float)cs_ptr->total)*100;
199 cpu_usage.kernel = ((float)cs_ptr->kernel / (float)cs_ptr->total)*100;
200 cpu_usage.idle = ((float)cs_ptr->idle / (float)cs_ptr->total)*100;
201 cpu_usage.iowait = ((float)cs_ptr->iowait / (float)cs_ptr->total)*100;
202 cpu_usage.swap = ((float)cs_ptr->swap / (float)cs_ptr->total)*100;
203 cpu_usage.nice = ((float)cs_ptr->nice / (float)cs_ptr->total)*100;
204 cpu_usage.time_taken = cs_ptr->systime;
205
206 return &cpu_usage;
207
208 }
209