ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/memory_stats.c
Revision: 1.20
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.19: +39 -2 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.18 /*
2 pajs 1.1 * i-scream central monitoring system
3 tdb 1.7 * http://www.i-scream.org
4 tdb 1.18 * Copyright (C) 2000-2004 i-scream
5 pajs 1.1 *
6 tdb 1.18 * 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.18 * 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.18 * 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.18 * 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
19     * 02111-1307 USA
20 tdb 1.19 *
21 tdb 1.20 * $Id: memory_stats.c,v 1.19 2004/01/19 16:49:21 tdb Exp $
22 pajs 1.1 */
23    
24     #ifdef HAVE_CONFIG_H
25     #include "config.h"
26     #endif
27    
28     #include "statgrab.h"
29 ats 1.12 #include "tools.h"
30 pajs 1.1 #ifdef SOLARIS
31     #include <unistd.h>
32     #include <kstat.h>
33     #endif
34 ats 1.17 #if defined(LINUX) || defined(CYGWIN)
35 pajs 1.5 #include <stdio.h>
36     #include <string.h>
37     #endif
38 pajs 1.6 #ifdef FREEBSD
39     #include <sys/types.h>
40     #include <sys/sysctl.h>
41     #include <unistd.h>
42     #endif
43 tdb 1.20 #ifdef OPENBSD
44     #include <stdlib.h>
45     #include <sys/param.h>
46     #include <sys/sysctl.h>
47     #include <uvm/uvm.h>
48     #endif
49 pajs 1.1
50     mem_stat_t *get_memory_stats(){
51    
52     static mem_stat_t mem_stat;
53    
54     #ifdef SOLARIS
55     kstat_ctl_t *kc;
56     kstat_t *ksp;
57     kstat_named_t *kn;
58     long totalmem;
59     int pagesize;
60     #endif
61 ats 1.17 #if defined(LINUX) || defined(CYGWIN)
62 pajs 1.5 char *line_ptr;
63 ats 1.15 unsigned long long value;
64 pajs 1.5 FILE *f;
65     #endif
66 ats 1.14 #ifdef FREEBSD
67 ats 1.12 int mib[2];
68 ats 1.14 u_long physmem;
69     size_t size;
70 tdb 1.8 u_int free_count;
71     u_int cache_count;
72     u_int inactive_count;
73 ats 1.12 int pagesize;
74     #endif
75 tdb 1.20 #if defined(NETBSD) || defined(OPENBSD)
76 ats 1.12 struct uvmexp *uvm;
77     #endif
78 tdb 1.20 #ifdef OPENBSD
79     int mib[2];
80     size_t size;
81     #endif
82 pajs 1.1
83     #ifdef SOLARIS
84     if((pagesize=sysconf(_SC_PAGESIZE)) == -1){
85     return NULL;
86     }
87    
88     if((totalmem=sysconf(_SC_PHYS_PAGES)) == -1){
89     return NULL;
90     }
91    
92     if ((kc = kstat_open()) == NULL) {
93     return NULL;
94     }
95     if((ksp=kstat_lookup(kc, "unix", 0, "system_pages")) == NULL){
96     return NULL;
97     }
98     if (kstat_read(kc, ksp, 0) == -1) {
99     return NULL;
100     }
101     if((kn=kstat_data_lookup(ksp, "freemem")) == NULL){
102     return NULL;
103     }
104 pajs 1.2 kstat_close(kc);
105    
106 pajs 1.1 mem_stat.total = (long long)totalmem * (long long)pagesize;
107     mem_stat.free = ((long long)kn->value.ul) * (long long)pagesize;
108     mem_stat.used = mem_stat.total - mem_stat.free;
109 pajs 1.5 #endif
110    
111 ats 1.17 #if defined(LINUX) || defined(CYGWIN)
112 ats 1.16 if ((f = fopen("/proc/meminfo", "r")) == NULL) {
113 pajs 1.5 return NULL;
114     }
115    
116 ats 1.15 while ((line_ptr = f_read_line(f, "")) != NULL) {
117 ats 1.16 if (sscanf(line_ptr, "%*s %llu kB", &value) != 1) {
118 ats 1.15 continue;
119     }
120     value *= 1024;
121    
122     if (strncmp(line_ptr, "MemTotal:", 9) == 0) {
123     mem_stat.total = value;
124     } else if (strncmp(line_ptr, "MemFree:", 8) == 0) {
125     mem_stat.free = value;
126     } else if (strncmp(line_ptr, "Cached:", 7) == 0) {
127     mem_stat.cache = value;
128     }
129 pajs 1.5 }
130    
131     fclose(f);
132 ats 1.15 mem_stat.used = mem_stat.total - mem_stat.free;
133 pajs 1.6 #endif
134    
135 ats 1.14 #ifdef FREEBSD
136 tdb 1.8 /* Returns bytes */
137 ats 1.12 mib[0] = CTL_HW;
138     mib[1] = HW_PHYSMEM;
139 ats 1.11 size = sizeof physmem;
140 ats 1.12 if (sysctl(mib, 2, &physmem, &size, NULL, 0) < 0) {
141 pajs 1.6 return NULL;
142 ats 1.12 }
143     mem_stat.total = physmem;
144 pajs 1.6
145     /*returns pages*/
146 ats 1.11 size = sizeof free_count;
147 ats 1.10 if (sysctlbyname("vm.stats.vm.v_free_count", &free_count, &size, NULL, 0) < 0){
148 pajs 1.6 return NULL;
149     }
150    
151 ats 1.11 size = sizeof inactive_count;
152 ats 1.10 if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count , &size, NULL, 0) < 0){
153 pajs 1.6 return NULL;
154     }
155    
156 ats 1.11 size = sizeof cache_count;
157 ats 1.10 if (sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &size, NULL, 0) < 0){
158 pajs 1.6 return NULL;
159     }
160    
161 tdb 1.8 /* Because all the vm.stats returns pages, I need to get the page size.
162     * After that I then need to multiple the anything that used vm.stats to
163     * get the system statistics by pagesize
164 pajs 1.6 */
165     if ((pagesize=getpagesize()) == -1){
166     return NULL;
167     }
168    
169 tdb 1.8 mem_stat.cache=cache_count*pagesize;
170    
171     /* Of couse nothing is ever that simple :) And I have inactive pages to
172     * deal with too. So I'm going to add them to free memory :)
173 pajs 1.6 */
174 tdb 1.8 mem_stat.free=(free_count*pagesize)+(inactive_count*pagesize);
175     mem_stat.used=physmem-mem_stat.free;
176 ats 1.12 #endif
177 ats 1.14
178 ats 1.12 #ifdef NETBSD
179     if ((uvm = get_uvmexp()) == NULL) {
180     return NULL;
181     }
182 tdb 1.20 #endif
183     #ifdef OPENBSD
184     mib[0] = CTL_VM;
185     mib[1] = VM_UVMEXP;
186    
187     if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0) {
188     return NULL;
189     }
190    
191     uvm = malloc(size);
192     if (uvm == NULL) {
193     return NULL;
194     }
195    
196     if (sysctl(mib, 2, uvm, &size, NULL, 0) < 0) {
197     return NULL;
198     }
199     #endif
200     #if defined(NETBSD) || defined(OPENBSD)
201 ats 1.14 mem_stat.total = uvm->pagesize * uvm->npages;
202 tdb 1.20 #ifdef NETBSD
203 ats 1.12 mem_stat.cache = uvm->pagesize * (uvm->filepages + uvm->execpages);
204 tdb 1.20 #else
205     mem_stat.cache = 0;
206     #endif
207 ats 1.14 mem_stat.free = uvm->pagesize * (uvm->free + uvm->inactive);
208     mem_stat.used = mem_stat.total - mem_stat.free;
209 tdb 1.20 #endif
210    
211     #ifdef OPENBSD
212     free(uvm);
213 pajs 1.1 #endif
214    
215     return &mem_stat;
216     }