ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/memory_stats.c
Revision: 1.8
Committed: Sat Oct 18 12:28:32 2003 UTC (20 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.7: +19 -16 lines
Log Message:
Fix the FreeBSD memory code. The sysctl calls are returning ints, not
long longs, so putting the values straight in to long longs was breaking.
Now put the values into ints and then fill in the structure afterwards.

This, for some reason, only showed up on FreeBSD 5.1/sparc64. The changed
code works on the other FreeBSD's too.

One bug still outstanding: on sparc64 the total memory isn't working.

File Contents

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