ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/cpu_stats.c
Revision: 1.1
Committed: Tue Feb 18 19:28:30 2003 UTC (21 years, 3 months ago) by pajs
Content type: text/plain
Branch: MAIN
Log Message:
The new revesion of libstatgrab, which is a complete rewrite essentially.

Firstly the data is now returned in structures rather than xml strings.
The structures returned are all static, so what ever calls the library doesn't
have to deal with the memory management of it.

Secondly the general efficency of the code is now significantly faster. It no
longer needs to fork a process, connect file descriptors and run ps, and then
parse the output like it used to. Now it walks /proc and reads it into the
correct data structures. This works without needing any special privilages, so
it can still run as a normal mortal without needing any special group. (Freebsd
will be an exception to this, but this commit only works with solaris, and that
requires nothing special)

Thridly it has more functionality than it used to. It not for instance is capable
of showing network traffic stats, (although its not completely finished yet). It
also in the near future be able to disk io stats as well. Several bug fixes have
been aplied over the original version. For example the cpu_stats used to only reply
the stats for the first processor. This now will report the total stats of all of
them. Paging stats will also be fixed, but haven't been done yet.

File Contents

# User Rev Content
1 pajs 1.1 /*
2     * i-scream central monitoring system
3     * http://www.i-scream.org.uk
4     * Copyright (C) 2000-2002 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 <stdio.h>
26     #include <ukcprog.h>
27     #include <unistd.h>
28     #include <stdlib.h>
29     #include <sys/types.h>
30     #include <time.h>
31     #include <string.h>
32     #include "statgrab.h"
33     #ifdef SOLARIS
34     #include <kstat.h>
35     #include <sys/sysinfo.h>
36     #endif
37     #ifdef FREEBSD
38     #include <sys/sysctl.h>
39     #include <sys/dkstat.h>
40     #endif
41    
42     static cpu_states_t cpu_now;
43     static int cpu_now_uninit=1;
44    
45    
46     cpu_states_t *get_cpu_totals(){
47    
48     #ifdef SOLARIS
49     kstat_ctl_t *kc;
50     kstat_t *ksp;
51     cpu_stat_t cs;
52    
53     cpu_now.user=0;
54     cpu_now.iowait=0;
55     cpu_now.kernel=0;
56     cpu_now.idle=0;
57     cpu_now.swap=0;
58     cpu_now.total=0;
59     /* Not stored in solaris */
60     cpu_now.nice=0;
61    
62     if ((kc = kstat_open()) == NULL) {
63     return NULL;
64     }
65     for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) {
66     if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue;
67     if (kstat_read(kc, ksp, &cs) == -1) {
68     continue;
69     }
70     cpu_now.user+=cs.cpu_sysinfo.cpu[CPU_USER];
71     cpu_now.iowait+=cs.cpu_sysinfo.cpu[CPU_WAIT];
72     cpu_now.kernel+=cs.cpu_sysinfo.cpu[CPU_KERNEL];
73     cpu_now.idle+=cs.cpu_sysinfo.cpu[CPU_IDLE];
74     cpu_now.swap+=cs.cpu_sysinfo.cpu[CPU_STATES];
75     }
76    
77     cpu_now.total=cpu_now.user+cpu_now.iowait+cpu_now.kernel+cpu_now.idle+cpu_now.swap;
78     cpu_now_uninit=0;
79    
80     if((kstat_close(kc)) != 0){
81     return NULL;
82     }
83    
84     #endif
85    
86     cpu_now.systime=time(NULL);
87    
88     return &cpu_now;
89     }
90    
91     cpu_states_t *get_cpu_diff(){
92     static cpu_states_t cpu_diff;
93     cpu_states_t cpu_then, *cpu_tmp;
94    
95     if (cpu_now_uninit){
96     if((cpu_tmp=get_cpu_totals())==NULL){
97     /* Should get_cpu_totals fail */
98     return NULL;
99     }
100     return cpu_tmp;
101     }
102    
103    
104     cpu_then.user=cpu_now.user;
105     cpu_then.kernel=cpu_now.kernel;
106     cpu_then.idle=cpu_now.idle;
107     cpu_then.iowait=cpu_now.iowait;
108     cpu_then.swap=cpu_now.swap;
109     cpu_then.nice=cpu_now.nice;
110     cpu_then.total=cpu_now.total;
111     cpu_then.systime=cpu_now.systime;
112    
113     if((cpu_tmp=get_cpu_totals())==NULL){
114     return NULL;
115     }
116    
117     cpu_diff.user = cpu_now.user - cpu_then.user;
118     cpu_diff.kernel = cpu_now.kernel - cpu_then.kernel;
119     cpu_diff.idle = cpu_now.idle - cpu_then.idle;
120     cpu_diff.iowait = cpu_now.iowait - cpu_then.iowait;
121     cpu_diff.swap = cpu_now.swap - cpu_then.swap;
122     cpu_diff.nice = cpu_now.nice - cpu_then.nice;
123     cpu_diff.total = cpu_now.total - cpu_then.total;
124     cpu_diff.systime = cpu_now.systime - cpu_then.systime;
125    
126     return &cpu_diff;
127     }
128    
129     cpu_percent_t *cpu_percent_usage(){
130     static cpu_percent_t cpu_usage;
131     cpu_states_t *cs_ptr;
132    
133     cs_ptr=get_cpu_diff();
134     if(cs_ptr==NULL){
135     return NULL;
136     }
137    
138     cpu_usage.user = ((float)cs_ptr->user / (float)cs_ptr->total)*100;
139     cpu_usage.kernel = ((float)cs_ptr->kernel / (float)cs_ptr->total)*100;
140     cpu_usage.idle = ((float)cs_ptr->idle / (float)cs_ptr->total)*100;
141     cpu_usage.iowait = ((float)cs_ptr->iowait / (float)cs_ptr->total)*100;
142     cpu_usage.swap = ((float)cs_ptr->swap / (float)cs_ptr->total)*100;
143     cpu_usage.nice = ((float)cs_ptr->nice / (float)cs_ptr->total)*100;
144     cpu_usage.time_taken = cs_ptr->systime;
145    
146     return &cpu_usage;
147    
148     }
149