Commit | Line | Data |
---|---|---|
4938384a | 1 | /* Calculate the size of physical memory. |
192cbe66 | 2 | Copyright 2000, 2001, 2003 Free Software Foundation, Inc. |
4938384a DD |
3 | |
4 | This program is free software; you can redistribute it and/or modify | |
5 | it under the terms of the GNU General Public License as published by | |
6 | the Free Software Foundation; either version 2, or (at your option) | |
7 | any later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program; if not, write to the Free Software Foundation, | |
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
17 | ||
cc529274 | 18 | /* Written by Paul Eggert. */ |
4938384a DD |
19 | |
20 | #if HAVE_CONFIG_H | |
21 | # include <config.h> | |
22 | #endif | |
23 | ||
24 | #if HAVE_UNISTD_H | |
25 | # include <unistd.h> | |
26 | #endif | |
27 | ||
28 | #if HAVE_SYS_PSTAT_H | |
29 | # include <sys/pstat.h> | |
30 | #endif | |
31 | ||
192cbe66 | 32 | #if HAVE_SYS_SYSMP_H |
cc529274 | 33 | # include <sys/sysmp.h> |
192cbe66 DD |
34 | #endif |
35 | ||
36 | #if HAVE_SYS_SYSINFO_H && HAVE_MACHINE_HAL_SYSINFO_H | |
cc529274 DD |
37 | # include <sys/sysinfo.h> |
38 | # include <machine/hal_sysinfo.h> | |
192cbe66 DD |
39 | #endif |
40 | ||
41 | #if HAVE_SYS_TABLE_H | |
cc529274 DD |
42 | # include <sys/table.h> |
43 | #endif | |
44 | ||
45 | #include <sys/types.h> | |
46 | ||
47 | #if HAVE_SYS_PARAM_H | |
48 | # include <sys/param.h> | |
49 | #endif | |
50 | ||
51 | #if HAVE_SYS_SYSCTL_H | |
52 | # include <sys/sysctl.h> | |
53 | #endif | |
54 | ||
55 | #if HAVE_SYS_SYSTEMCFG_H | |
56 | # include <sys/systemcfg.h> | |
192cbe66 DD |
57 | #endif |
58 | ||
59 | #include "libiberty.h" | |
60 | ||
4938384a DD |
61 | /* Return the total amount of physical memory. */ |
62 | double | |
900d2082 | 63 | physmem_total () |
4938384a DD |
64 | { |
65 | #if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE | |
66 | { | |
67 | double pages = sysconf (_SC_PHYS_PAGES); | |
68 | double pagesize = sysconf (_SC_PAGESIZE); | |
69 | if (0 <= pages && 0 <= pagesize) | |
70 | return pages * pagesize; | |
71 | } | |
72 | #endif | |
73 | ||
74 | #if HAVE_PSTAT_GETSTATIC | |
192cbe66 | 75 | { /* This works on hpux11. */ |
4938384a DD |
76 | struct pst_static pss; |
77 | if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0)) | |
78 | { | |
79 | double pages = pss.physical_memory; | |
80 | double pagesize = pss.page_size; | |
81 | if (0 <= pages && 0 <= pagesize) | |
82 | return pages * pagesize; | |
83 | } | |
84 | } | |
85 | #endif | |
86 | ||
192cbe66 DD |
87 | #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE |
88 | { /* This works on irix6. */ | |
89 | struct rminfo realmem; | |
cc529274 | 90 | if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0) |
192cbe66 DD |
91 | { |
92 | double pagesize = sysconf (_SC_PAGESIZE); | |
93 | double pages = realmem.physmem; | |
94 | if (0 <= pages && 0 <= pagesize) | |
95 | return pages * pagesize; | |
96 | } | |
97 | } | |
98 | #endif | |
99 | ||
100 | #if HAVE_GETSYSINFO | |
101 | { /* This works on Tru64 UNIX V4/5. */ | |
102 | int physmem; | |
103 | ||
104 | if (getsysinfo (GSI_PHYSMEM, (caddr_t) &physmem, sizeof (physmem), | |
105 | NULL, NULL, NULL) == 1) | |
106 | { | |
107 | double kbytes = physmem; | |
108 | ||
109 | if (0 <= kbytes) | |
110 | return kbytes * 1024.0; | |
111 | } | |
112 | } | |
113 | #endif | |
114 | ||
cc529274 DD |
115 | #if HAVE_SYSCTL && defined HW_PHYSMEM |
116 | { /* This works on *bsd and darwin. */ | |
117 | unsigned int physmem; | |
118 | size_t len = sizeof(physmem); | |
119 | static int mib[2] = {CTL_HW, HW_PHYSMEM}; | |
120 | ||
121 | if (sysctl(mib, ARRAY_SIZE(mib), &physmem, &len, NULL, 0) == 0 | |
122 | && len == sizeof (physmem)) | |
123 | return (double)physmem; | |
124 | } | |
125 | #endif | |
126 | ||
127 | #if HAVE__SYSTEM_CONFIGURATION | |
128 | /* This works on AIX. */ | |
129 | return _system_configuration.physmem; | |
130 | #endif | |
131 | ||
4938384a DD |
132 | /* Return 0 if we can't determine the value. */ |
133 | return 0; | |
134 | } | |
135 | ||
136 | /* Return the amount of physical memory available. */ | |
137 | double | |
900d2082 | 138 | physmem_available () |
4938384a DD |
139 | { |
140 | #if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE | |
141 | { | |
142 | double pages = sysconf (_SC_AVPHYS_PAGES); | |
143 | double pagesize = sysconf (_SC_PAGESIZE); | |
144 | if (0 <= pages && 0 <= pagesize) | |
145 | return pages * pagesize; | |
146 | } | |
147 | #endif | |
148 | ||
149 | #if HAVE_PSTAT_GETSTATIC && HAVE_PSTAT_GETDYNAMIC | |
192cbe66 | 150 | { /* This works on hpux11. */ |
4938384a DD |
151 | struct pst_static pss; |
152 | struct pst_dynamic psd; | |
153 | if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0) | |
154 | && 0 <= pstat_getdynamic (&psd, sizeof psd, 1, 0)) | |
155 | { | |
156 | double pages = psd.psd_free; | |
157 | double pagesize = pss.page_size; | |
158 | if (0 <= pages && 0 <= pagesize) | |
159 | return pages * pagesize; | |
160 | } | |
161 | } | |
162 | #endif | |
163 | ||
192cbe66 DD |
164 | #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE |
165 | { /* This works on irix6. */ | |
166 | struct rminfo realmem; | |
cc529274 | 167 | if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0) |
192cbe66 DD |
168 | { |
169 | double pagesize = sysconf (_SC_PAGESIZE); | |
170 | double pages = realmem.availrmem; | |
171 | if (0 <= pages && 0 <= pagesize) | |
172 | return pages * pagesize; | |
173 | } | |
174 | } | |
175 | #endif | |
176 | ||
177 | #if HAVE_TABLE && HAVE_SYS_TABLE_H | |
178 | { /* This works on Tru64 UNIX V4/5. */ | |
179 | struct tbl_vmstats vmstats; | |
180 | ||
181 | if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1) | |
182 | { | |
183 | double pages = vmstats.free_count; | |
184 | double pagesize = vmstats.pagesize; | |
185 | ||
186 | if (0 <= pages && 0 <= pagesize) | |
187 | return pages * pagesize; | |
188 | } | |
189 | } | |
190 | #endif | |
191 | ||
cc529274 DD |
192 | #if HAVE_SYSCTL && defined HW_USERMEM |
193 | { /* This works on *bsd and darwin. */ | |
194 | unsigned int usermem; | |
195 | size_t len = sizeof(usermem); | |
196 | static int mib[2] = {CTL_HW, HW_USERMEM}; | |
197 | ||
198 | if (sysctl(mib, ARRAY_SIZE(mib), &usermem, &len, NULL, 0) == 0 | |
199 | && len == sizeof (usermem)) | |
200 | return (double)usermem; | |
201 | } | |
202 | #endif | |
203 | ||
4938384a DD |
204 | /* Guess 25% of physical memory. */ |
205 | return physmem_total () / 4; | |
206 | } | |
192cbe66 DD |
207 | |
208 | ||
209 | #if DEBUG | |
210 | ||
211 | # include <stdio.h> | |
212 | # include <stdlib.h> | |
213 | ||
214 | int | |
215 | main () | |
216 | { | |
217 | printf ("%12.f %12.f\n", physmem_total (), physmem_available ()); | |
218 | exit (0); | |
219 | } | |
220 | ||
221 | #endif /* DEBUG */ | |
222 | ||
223 | /* | |
224 | Local Variables: | |
225 | compile-command: "gcc -DDEBUG -DHAVE_CONFIG_H -I.. -g -O -Wall -W physmem.c" | |
226 | End: | |
227 | */ |