ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/memory_stats.c
Revision: 1.12
Committed: Sun Oct 19 02:03:02 2003 UTC (20 years, 7 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.11: +31 -6 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

# User Rev Content
1 pajs 1.1 /*
2     * i-scream central monitoring system
3 tdb 1.7 * http://www.i-scream.org
4     * Copyright (C) 2000-2003 i-scream
5 pajs 1.1 *
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 "statgrab.h"
26 ats 1.12 #include "tools.h"
27 pajs 1.1 #ifdef SOLARIS
28     #include <unistd.h>
29     #include <kstat.h>
30     #endif
31 pajs 1.5 #ifdef LINUX
32     #include <stdio.h>
33     #include <string.h>
34     #endif
35 ats 1.12 #ifdef ALLBSD
36 pajs 1.6 #ifdef FREEBSD
37     #include <sys/types.h>
38     #include <sys/sysctl.h>
39 ats 1.12 #else
40     #include <sys/param.h>
41     #include <sys/sysctl.h>
42     #endif
43 pajs 1.6 #include <unistd.h>
44     #endif
45 pajs 1.1
46     mem_stat_t *get_memory_stats(){
47    
48     static mem_stat_t mem_stat;
49    
50     #ifdef SOLARIS
51     kstat_ctl_t *kc;
52     kstat_t *ksp;
53     kstat_named_t *kn;
54     long totalmem;
55     int pagesize;
56     #endif
57 pajs 1.5 #ifdef LINUX
58     char *line_ptr;
59     FILE *f;
60     #endif
61 ats 1.12 #ifdef ALLBSD
62     int mib[2];
63 pajs 1.6 #ifdef FREEBSD
64 tdb 1.8 u_int free_count;
65     u_int cache_count;
66     u_int inactive_count;
67 ats 1.12 int pagesize;
68     #endif
69     #ifdef NETBSD
70     struct uvmexp *uvm;
71     #endif
72 tdb 1.9 u_long physmem;
73 pajs 1.6 size_t size;
74     #endif
75 pajs 1.1
76     #ifdef SOLARIS
77     if((pagesize=sysconf(_SC_PAGESIZE)) == -1){
78     return NULL;
79     }
80    
81     if((totalmem=sysconf(_SC_PHYS_PAGES)) == -1){
82     return NULL;
83     }
84    
85     if ((kc = kstat_open()) == NULL) {
86     return NULL;
87     }
88     if((ksp=kstat_lookup(kc, "unix", 0, "system_pages")) == NULL){
89     return NULL;
90     }
91     if (kstat_read(kc, ksp, 0) == -1) {
92     return NULL;
93     }
94     if((kn=kstat_data_lookup(ksp, "freemem")) == NULL){
95     return NULL;
96     }
97 pajs 1.2 kstat_close(kc);
98    
99 pajs 1.1 mem_stat.total = (long long)totalmem * (long long)pagesize;
100     mem_stat.free = ((long long)kn->value.ul) * (long long)pagesize;
101     mem_stat.used = mem_stat.total - mem_stat.free;
102 pajs 1.5 #endif
103    
104     #ifdef LINUX
105     f=fopen("/proc/meminfo", "r");
106     if(f==NULL){
107     return NULL;
108     }
109    
110     if((line_ptr=f_read_line(f, "Mem:"))==NULL){
111     fclose(f);
112     return NULL;
113     }
114    
115     fclose(f);
116    
117     /* Linux actually stores this as a unsigned long long, but
118     * our structures are just long longs. This shouldn't be a
119     * problem for sometime yet :)
120     */
121     if((sscanf(line_ptr,"Mem: %lld %lld %lld %*d %*d %lld", \
122 ats 1.12 size = sizeof physmem;
123 pajs 1.5 &mem_stat.total, \
124     &mem_stat.used, \
125     &mem_stat.free, \
126     &mem_stat.cache))!=4){
127     return NULL;
128     }
129 pajs 1.6
130     #endif
131    
132 ats 1.12 #ifdef ALLBSD
133 tdb 1.8 /* Returns bytes */
134 ats 1.12 mib[0] = CTL_HW;
135     mib[1] = HW_PHYSMEM;
136 ats 1.11 size = sizeof physmem;
137 ats 1.12 if (sysctl(mib, 2, &physmem, &size, NULL, 0) < 0) {
138 pajs 1.6 return NULL;
139 ats 1.12 }
140     mem_stat.total = physmem;
141 pajs 1.6
142     /*returns pages*/
143 ats 1.12 #ifdef FREEBSD
144 ats 1.11 size = sizeof free_count;
145 ats 1.10 if (sysctlbyname("vm.stats.vm.v_free_count", &free_count, &size, NULL, 0) < 0){
146 pajs 1.6 return NULL;
147     }
148    
149 ats 1.11 size = sizeof inactive_count;
150 ats 1.10 if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count , &size, NULL, 0) < 0){
151 pajs 1.6 return NULL;
152     }
153    
154 ats 1.11 size = sizeof cache_count;
155 ats 1.10 if (sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &size, NULL, 0) < 0){
156 pajs 1.6 return NULL;
157     }
158    
159 tdb 1.8 /* Because all the vm.stats returns pages, I need to get the page size.
160     * After that I then need to multiple the anything that used vm.stats to
161     * get the system statistics by pagesize
162 pajs 1.6 */
163     if ((pagesize=getpagesize()) == -1){
164     return NULL;
165     }
166    
167 tdb 1.8 mem_stat.cache=cache_count*pagesize;
168    
169     /* Of couse nothing is ever that simple :) And I have inactive pages to
170     * deal with too. So I'm going to add them to free memory :)
171 pajs 1.6 */
172 tdb 1.8 mem_stat.free=(free_count*pagesize)+(inactive_count*pagesize);
173     mem_stat.used=physmem-mem_stat.free;
174 ats 1.12 #endif
175     #ifdef NETBSD
176     /* FIXME This is not consistent with the FreeBSD logic above. */
177     if ((uvm = get_uvmexp()) == NULL) {
178     return NULL;
179     }
180     mem_stat.cache = uvm->pagesize * (uvm->filepages + uvm->execpages);
181     mem_stat.free = uvm->pagesize * uvm->free;
182     mem_stat.used = uvm->pagesize * (uvm->npages - uvm->free);
183     #endif
184 pajs 1.1 #endif
185    
186     return &mem_stat;
187    
188     }