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

# User Rev Content
1 tdb 1.16 /*
2 pajs 1.1 * i-scream central monitoring system
3 tdb 1.10 * http://www.i-scream.org
4 tdb 1.16 * Copyright (C) 2000-2004 i-scream
5 pajs 1.1 *
6 tdb 1.16 * 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 pajs 1.1 *
11 tdb 1.16 * This library is distributed in the hope that it will be useful,
12 pajs 1.1 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 tdb 1.16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     * Lesser General Public License for more details.
15 pajs 1.1 *
16 tdb 1.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 tdb 1.17 *
20 tdb 1.18 * $Id: cpu_stats.c,v 1.17 2004/01/19 16:49:21 tdb Exp $
21 pajs 1.1 */
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 pajs 1.6 #include <string.h>
33 pajs 1.1 #endif
34 ats 1.14 #if defined(LINUX) || defined(CYGWIN)
35 pajs 1.7 #include <stdio.h>
36     #endif
37 pajs 1.9 #ifdef FREEBSD
38     #include <sys/sysctl.h>
39     #include <sys/dkstat.h>
40     #endif
41 ats 1.13 #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 tdb 1.18 #ifdef OPENBSD
48     #include <sys/param.h>
49     #include <sys/sysctl.h>
50     #include <sys/dkstat.h>
51     #endif
52 pajs 1.1
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 pajs 1.7 cpu_stat_t cs;
62     #endif
63 tdb 1.15 #if defined(LINUX) || defined(CYGWIN)
64 pajs 1.7 FILE *f;
65     #endif
66 ats 1.13 #ifdef ALLBSD
67     #ifndef FREEBSD
68     int mib[2];
69     #endif
70     #ifdef NETBSD
71     u_int64_t cp_time[CPUSTATES];
72     #else
73 pajs 1.9 long cp_time[CPUSTATES];
74 ats 1.13 #endif
75 pajs 1.9 size_t size;
76     #endif
77 pajs 1.7
78 pajs 1.1 cpu_now.user=0;
79 pajs 1.9 /* Not stored in linux or freebsd */
80 pajs 1.1 cpu_now.iowait=0;
81     cpu_now.kernel=0;
82     cpu_now.idle=0;
83 pajs 1.9 /* Not stored in linux or freebsd */
84 pajs 1.1 cpu_now.swap=0;
85     cpu_now.total=0;
86     /* Not stored in solaris */
87     cpu_now.nice=0;
88    
89 pajs 1.7 #ifdef SOLARIS
90 pajs 1.1 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 pajs 1.5 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 pajs 1.1 }
104    
105     cpu_now.total=cpu_now.user+cpu_now.iowait+cpu_now.kernel+cpu_now.idle+cpu_now.swap;
106 pajs 1.7
107     kstat_close(kc);
108     #endif
109 ats 1.14 #if defined(LINUX) || defined(CYGWIN)
110 pajs 1.7 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 pajs 1.8 fclose(f);
120 pajs 1.7 return NULL;
121     }
122    
123     fclose(f);
124 pajs 1.1
125 pajs 1.7 cpu_now.total=cpu_now.user+cpu_now.nice+cpu_now.kernel+cpu_now.idle;
126 pajs 1.9 #endif
127 ats 1.13 #ifdef ALLBSD
128 pajs 1.9 #ifdef FREEBSD
129 ats 1.12 size = sizeof cp_time;
130 ats 1.11 if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) < 0){
131 pajs 1.9 return NULL;
132     }
133 ats 1.13 #else
134     mib[0] = CTL_KERN;
135 tdb 1.18 #ifdef NETBSD
136 ats 1.13 mib[1] = KERN_CP_TIME;
137 tdb 1.18 #else
138     mib[1] = KERN_CPTIME;
139     #endif
140 ats 1.13 size = sizeof cp_time;
141     if (sysctl(mib, 2, &cp_time, &size, NULL, 0) < 0) {
142     return NULL;
143     }
144     #endif
145 pajs 1.9
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 pajs 1.1 #endif
154    
155     cpu_now.systime=time(NULL);
156 pajs 1.7 cpu_now_uninit=0;
157    
158 pajs 1.1
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