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

# 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     #ifdef SOLARIS
27     #include <unistd.h>
28     #include <kstat.h>
29     #endif
30 pajs 1.5 #ifdef LINUX
31     #include <stdio.h>
32     #include <string.h>
33     #include "tools.h"
34     #endif
35 pajs 1.6 #ifdef FREEBSD
36     #include <sys/types.h>
37     #include <sys/sysctl.h>
38     #include <unistd.h>
39     #endif
40 pajs 1.1
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 pajs 1.5 #ifdef LINUX
53     char *line_ptr;
54     FILE *f;
55     #endif
56 pajs 1.6 #ifdef FREEBSD
57 tdb 1.8 u_int free_count;
58     u_int cache_count;
59     u_int inactive_count;
60     u_int physmem;
61 pajs 1.6 size_t size;
62     int pagesize;
63     #endif
64 pajs 1.1
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 pajs 1.2 kstat_close(kc);
87    
88 pajs 1.1 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 pajs 1.5 #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 pajs 1.6
118     #endif
119    
120     #ifdef FREEBSD
121 tdb 1.8 /* Returns bytes */
122 pajs 1.6 if (sysctlbyname("hw.physmem", NULL, &size, NULL, NULL) < 0){
123     return NULL;
124     }
125 tdb 1.8 if (sysctlbyname("hw.physmem", &physmem, &size, NULL, NULL) < 0){
126 pajs 1.6 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 tdb 1.8 if (sysctlbyname("vm.stats.vm.v_free_count", &free_count, &size, NULL, NULL) < 0){
134 pajs 1.6 return NULL;
135     }
136    
137     if (sysctlbyname("vm.stats.vm.v_inactive_count", NULL, &size, NULL, NULL) < 0){
138     return NULL;
139     }
140 tdb 1.8 if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count , &size, NULL, NULL) < 0){
141 pajs 1.6 return NULL;
142     }
143    
144     if (sysctlbyname("vm.stats.vm.v_cache_count", NULL, &size, NULL, NULL) < 0){
145     return NULL;
146     }
147 tdb 1.8 if (sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &size, NULL, NULL) < 0){
148 pajs 1.6 return NULL;
149     }
150    
151 tdb 1.8 /* 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 pajs 1.6 */
155     if ((pagesize=getpagesize()) == -1){
156     return NULL;
157     }
158    
159 tdb 1.8 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 pajs 1.6 */
165 tdb 1.8 mem_stat.free=(free_count*pagesize)+(inactive_count*pagesize);
166     mem_stat.used=physmem-mem_stat.free;
167 pajs 1.1 #endif
168    
169     return &mem_stat;
170    
171     }