ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/memory_stats.c
Revision: 1.27
Committed: Wed Apr 7 21:08:40 2004 UTC (20 years, 1 month ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_10
Changes since 1.26: +20 -8 lines
Log Message:
The rest of the error handling stuff (except the vector code).

I've been extremely unimaginative with the string names in error.c, but
they're all in one place so much easier to tidy up. I'm also beginning to
wonder if we actually needed an SG_ERROR_SYSTEM_CALL to indicate some call
into the system failed - because the majority of our errors are those :-)

Still to do, then:
 - vector code
 - better string names in error.c
 - deal with arg string in some way
 - make use of the error status in statgrab/saidar/examples

File Contents

# Content
1 /*
2 * i-scream libstatgrab
3 * http://www.i-scream.org
4 * Copyright (C) 2000-2004 i-scream
5 *
6 * 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 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
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
19 * 02111-1307 USA
20 *
21 * $Id: memory_stats.c,v 1.26 2004/04/07 14:53:40 tdb Exp $
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "statgrab.h"
29 #include "tools.h"
30 #ifdef SOLARIS
31 #include <unistd.h>
32 #include <kstat.h>
33 #endif
34 #if defined(LINUX) || defined(CYGWIN)
35 #include <stdio.h>
36 #include <string.h>
37 #endif
38 #if defined(FREEBSD) || defined(DFBSD)
39 #include <sys/types.h>
40 #include <sys/sysctl.h>
41 #include <unistd.h>
42 #endif
43 #if defined(NETBSD) || defined(OPENBSD)
44 #include <sys/param.h>
45 #include <sys/time.h>
46 #include <uvm/uvm.h>
47 #endif
48
49 sg_mem_stats *sg_get_mem_stats(){
50
51 static sg_mem_stats mem_stat;
52
53 #ifdef SOLARIS
54 kstat_ctl_t *kc;
55 kstat_t *ksp;
56 kstat_named_t *kn;
57 long totalmem;
58 int pagesize;
59 #endif
60 #if defined(LINUX) || defined(CYGWIN)
61 char *line_ptr;
62 unsigned long long value;
63 FILE *f;
64 #endif
65 #if defined(FREEBSD) || defined(DFBSD)
66 int mib[2];
67 u_long physmem;
68 size_t size;
69 u_int free_count;
70 u_int cache_count;
71 u_int inactive_count;
72 int pagesize;
73 #endif
74 #if defined(NETBSD) || defined(OPENBSD)
75 struct uvmexp *uvm;
76 #endif
77
78 #ifdef SOLARIS
79 if((pagesize=sysconf(_SC_PAGESIZE)) == -1){
80 sg_set_error(SG_ERROR_SYSCONF, "_SC_PAGESIZE");
81 return NULL;
82 }
83
84 if((totalmem=sysconf(_SC_PHYS_PAGES)) == -1){
85 sg_set_error(SG_ERROR_SYSCONF, "_SC_PHYS_PAGES");
86 return NULL;
87 }
88
89 if ((kc = kstat_open()) == NULL) {
90 sg_set_error(SG_ERROR_KSTAT_OPEN, NULL);
91 return NULL;
92 }
93 if((ksp=kstat_lookup(kc, "unix", 0, "system_pages")) == NULL){
94 sg_set_error(SG_ERROR_KSTAT_LOOKUP, "unix,0,system_pages");
95 return NULL;
96 }
97 if (kstat_read(kc, ksp, 0) == -1) {
98 sg_set_error(SG_ERROR_KSTAT_READ, NULL);
99 return NULL;
100 }
101 if((kn=kstat_data_lookup(ksp, "freemem")) == NULL){
102 sg_set_error(SG_ERROR_KSTAT_DATA_LOOKUP, "freemem");
103 return NULL;
104 }
105 kstat_close(kc);
106
107 mem_stat.total = (long long)totalmem * (long long)pagesize;
108 mem_stat.free = ((long long)kn->value.ul) * (long long)pagesize;
109 mem_stat.used = mem_stat.total - mem_stat.free;
110 #endif
111
112 #if defined(LINUX) || defined(CYGWIN)
113 if ((f = fopen("/proc/meminfo", "r")) == NULL) {
114 sg_set_error(SG_ERROR_OPEN, "/proc/meminfo");
115 return NULL;
116 }
117
118 while ((line_ptr = sg_f_read_line(f, "")) != NULL) {
119 if (sscanf(line_ptr, "%*s %llu kB", &value) != 1) {
120 continue;
121 }
122 value *= 1024;
123
124 if (strncmp(line_ptr, "MemTotal:", 9) == 0) {
125 mem_stat.total = value;
126 } else if (strncmp(line_ptr, "MemFree:", 8) == 0) {
127 mem_stat.free = value;
128 } else if (strncmp(line_ptr, "Cached:", 7) == 0) {
129 mem_stat.cache = value;
130 }
131 }
132
133 fclose(f);
134 mem_stat.used = mem_stat.total - mem_stat.free;
135 #endif
136
137 #if defined(FREEBSD) || defined(DFBSD)
138 /* Returns bytes */
139 mib[0] = CTL_HW;
140 mib[1] = HW_PHYSMEM;
141 size = sizeof physmem;
142 if (sysctl(mib, 2, &physmem, &size, NULL, 0) < 0) {
143 sg_set_error(SG_ERROR_SYSCTL, "CTL_HW.HW_PHYSMEM");
144 return NULL;
145 }
146 mem_stat.total = physmem;
147
148 /*returns pages*/
149 size = sizeof free_count;
150 if (sysctlbyname("vm.stats.vm.v_free_count", &free_count, &size, NULL, 0) < 0){
151 sg_set_error(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_free_count");
152 return NULL;
153 }
154
155 size = sizeof inactive_count;
156 if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count , &size, NULL, 0) < 0){
157 sg_set_error(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_inactive_count");
158 return NULL;
159 }
160
161 size = sizeof cache_count;
162 if (sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &size, NULL, 0) < 0){
163 sg_set_error(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_cache_count");
164 return NULL;
165 }
166
167 /* Because all the vm.stats returns pages, I need to get the page size.
168 * After that I then need to multiple the anything that used vm.stats to
169 * get the system statistics by pagesize
170 */
171 if ((pagesize=getpagesize()) == -1){
172 sg_set_error(SG_ERROR_GETPAGESIZE, "NULL");
173 return NULL;
174 }
175
176 mem_stat.cache=cache_count*pagesize;
177
178 /* Of couse nothing is ever that simple :) And I have inactive pages to
179 * deal with too. So I'm going to add them to free memory :)
180 */
181 mem_stat.free=(free_count*pagesize)+(inactive_count*pagesize);
182 mem_stat.used=physmem-mem_stat.free;
183 #endif
184
185 #if defined(NETBSD) || defined(OPENBSD)
186 if ((uvm = sg_get_uvmexp()) == NULL) {
187 return NULL;
188 }
189
190 mem_stat.total = uvm->pagesize * uvm->npages;
191 #ifdef NETBSD
192 mem_stat.cache = uvm->pagesize * (uvm->filepages + uvm->execpages);
193 #else
194 /* Can't find cache memory on OpenBSD */
195 mem_stat.cache = 0;
196 #endif
197 mem_stat.free = uvm->pagesize * (uvm->free + uvm->inactive);
198 mem_stat.used = mem_stat.total - mem_stat.free;
199 #endif
200
201 return &mem_stat;
202 }