Mercurial > hg > octave-jordi > gnulib-hg
comparison lib/physmem.c @ 4551:e98bdaad6174
Merge in portability changes from gcc/libiberty
to support AIX, IRIX, Tru64, and Windows. See the ChangeLog there
for credits and details. Thanks to Kaveh Ghazi for helping
to keep these files in sync.
(ARRAY_SIZE): Define it.
(physmem_total, physmem_available): Add comments. From Kaveh Ghazi.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Fri, 15 Aug 2003 03:23:11 +0000 |
parents | 0eb39272f531 |
children | c7ad68a45173 |
comparison
equal
deleted
inserted
replaced
4550:6070487cf52f | 4551:e98bdaad6174 |
---|---|
1 /* Calculate the size of physical memory. | 1 /* Calculate the size of physical memory. |
2 Copyright 2000, 2001 Free Software Foundation, Inc. | 2 Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. |
3 | 3 |
4 This program is free software; you can redistribute it and/or modify | 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 | 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) | 6 the Free Software Foundation; either version 2, or (at your option) |
7 any later version. | 7 any later version. |
29 | 29 |
30 #if HAVE_SYS_PSTAT_H | 30 #if HAVE_SYS_PSTAT_H |
31 # include <sys/pstat.h> | 31 # include <sys/pstat.h> |
32 #endif | 32 #endif |
33 | 33 |
34 #if HAVE_SYS_SYSMP_H | |
35 # include <sys/sysmp.h> | |
36 #endif | |
37 | |
38 #if HAVE_SYS_SYSINFO_H && HAVE_MACHINE_HAL_SYSINFO_H | |
39 # include <sys/sysinfo.h> | |
40 # include <machine/hal_sysinfo.h> | |
41 #endif | |
42 | |
43 #if HAVE_SYS_TABLE_H | |
44 # include <sys/table.h> | |
45 #endif | |
46 | |
47 #include <sys/types.h> | |
48 | |
49 #if HAVE_SYS_PARAM_H | |
50 # include <sys/param.h> | |
51 #endif | |
52 | |
53 #if HAVE_SYS_SYSCTL_H | |
54 # include <sys/sysctl.h> | |
55 #endif | |
56 | |
57 #if HAVE_SYS_SYSTEMCFG_H | |
58 # include <sys/systemcfg.h> | |
59 #endif | |
60 | |
61 #ifdef _WIN32 | |
62 # define WIN32_LEAN_AND_MEAN | |
63 # include <windows.h> | |
64 /* MEMORYSTATUSEX is missing from older windows headers, so define | |
65 a local replacement. */ | |
66 typedef struct | |
67 { | |
68 DWORD dwLength; | |
69 DWORD dwMemoryLoad; | |
70 DWORDLONG ullTotalPhys; | |
71 DWORDLONG ullAvailPhys; | |
72 DWORDLONG ullTotalPageFile; | |
73 DWORDLONG ullAvailPageFile; | |
74 DWORDLONG ullTotalVirtual; | |
75 DWORDLONG ullAvailVirtual; | |
76 DWORDLONG ullAvailExtendedVirtual; | |
77 } lMEMORYSTATUSEX; | |
78 typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*); | |
79 #endif | |
80 | |
81 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) | |
82 | |
34 /* Return the total amount of physical memory. */ | 83 /* Return the total amount of physical memory. */ |
35 double | 84 double |
36 physmem_total (void) | 85 physmem_total () |
37 { | 86 { |
38 #if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE | 87 #if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE |
39 { | 88 { /* This works on linux-gnu, solaris2 and cygwin. */ |
40 double pages = sysconf (_SC_PHYS_PAGES); | 89 double pages = sysconf (_SC_PHYS_PAGES); |
41 double pagesize = sysconf (_SC_PAGESIZE); | 90 double pagesize = sysconf (_SC_PAGESIZE); |
42 if (0 <= pages && 0 <= pagesize) | 91 if (0 <= pages && 0 <= pagesize) |
43 return pages * pagesize; | 92 return pages * pagesize; |
44 } | 93 } |
45 #endif | 94 #endif |
46 | 95 |
47 #if HAVE_PSTAT_GETSTATIC | 96 #if HAVE_PSTAT_GETSTATIC |
48 { | 97 { /* This works on hpux11. */ |
49 struct pst_static pss; | 98 struct pst_static pss; |
50 if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0)) | 99 if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0)) |
51 { | 100 { |
52 double pages = pss.physical_memory; | 101 double pages = pss.physical_memory; |
53 double pagesize = pss.page_size; | 102 double pagesize = pss.page_size; |
54 if (0 <= pages && 0 <= pagesize) | 103 if (0 <= pages && 0 <= pagesize) |
55 return pages * pagesize; | 104 return pages * pagesize; |
105 } | |
106 } | |
107 #endif | |
108 | |
109 #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE | |
110 { /* This works on irix6. */ | |
111 struct rminfo realmem; | |
112 if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0) | |
113 { | |
114 double pagesize = sysconf (_SC_PAGESIZE); | |
115 double pages = realmem.physmem; | |
116 if (0 <= pages && 0 <= pagesize) | |
117 return pages * pagesize; | |
118 } | |
119 } | |
120 #endif | |
121 | |
122 #if HAVE_GETSYSINFO && defined GSI_PHYSMEM | |
123 { /* This works on Tru64 UNIX V4/5. */ | |
124 int physmem; | |
125 | |
126 if (getsysinfo (GSI_PHYSMEM, (caddr_t) &physmem, sizeof (physmem), | |
127 NULL, NULL, NULL) == 1) | |
128 { | |
129 double kbytes = physmem; | |
130 | |
131 if (0 <= kbytes) | |
132 return kbytes * 1024.0; | |
133 } | |
134 } | |
135 #endif | |
136 | |
137 #if HAVE_SYSCTL && defined HW_PHYSMEM | |
138 { /* This works on *bsd and darwin. */ | |
139 unsigned int physmem; | |
140 size_t len = sizeof physmem; | |
141 static int mib[2] = { CTL_HW, HW_PHYSMEM }; | |
142 | |
143 if (sysctl (mib, ARRAY_SIZE (mib), &physmem, &len, NULL, 0) == 0 | |
144 && len == sizeof (physmem)) | |
145 return (double) physmem; | |
146 } | |
147 #endif | |
148 | |
149 #if HAVE__SYSTEM_CONFIGURATION | |
150 /* This works on AIX. */ | |
151 return _system_configuration.physmem; | |
152 #endif | |
153 | |
154 #if defined _WIN32 | |
155 { /* this works on windows */ | |
156 PFN_MS_EX pfnex; | |
157 HMODULE h = GetModuleHandle ("kernel32.dll"); | |
158 | |
159 if (!h) | |
160 return 0.0; | |
161 | |
162 /* Use GlobalMemoryStatusEx if available. */ | |
163 if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx"))) | |
164 { | |
165 lMEMORYSTATUSEX lms_ex; | |
166 lms_ex.dwLength = sizeof lms_ex; | |
167 if (!pfnex (&lms_ex)) | |
168 return 0.0; | |
169 return (double) lms_ex.ullTotalPhys; | |
170 } | |
171 | |
172 /* Fall back to GlobalMemoryStatus which is always available. | |
173 but returns wrong results for physical memory > 4GB. */ | |
174 else | |
175 { | |
176 MEMORYSTATUS ms; | |
177 GlobalMemoryStatus (&ms); | |
178 return (double) ms.dwTotalPhys; | |
56 } | 179 } |
57 } | 180 } |
58 #endif | 181 #endif |
59 | 182 |
60 /* Guess 64 MB. It's probably an older host, so guess small. */ | 183 /* Guess 64 MB. It's probably an older host, so guess small. */ |
61 return 64 * 1024 * 1024; | 184 return 64 * 1024 * 1024; |
62 } | 185 } |
63 | 186 |
64 /* Return the amount of physical memory available. */ | 187 /* Return the amount of physical memory available. */ |
65 double | 188 double |
66 physmem_available (void) | 189 physmem_available () |
67 { | 190 { |
68 #if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE | 191 #if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE |
69 { | 192 { /* This works on linux-gnu, solaris2 and cygwin. */ |
70 double pages = sysconf (_SC_AVPHYS_PAGES); | 193 double pages = sysconf (_SC_AVPHYS_PAGES); |
71 double pagesize = sysconf (_SC_PAGESIZE); | 194 double pagesize = sysconf (_SC_PAGESIZE); |
72 if (0 <= pages && 0 <= pagesize) | 195 if (0 <= pages && 0 <= pagesize) |
73 return pages * pagesize; | 196 return pages * pagesize; |
74 } | 197 } |
75 #endif | 198 #endif |
76 | 199 |
77 #if HAVE_PSTAT_GETSTATIC && HAVE_PSTAT_GETDYNAMIC | 200 #if HAVE_PSTAT_GETSTATIC && HAVE_PSTAT_GETDYNAMIC |
78 { | 201 { /* This works on hpux11. */ |
79 struct pst_static pss; | 202 struct pst_static pss; |
80 struct pst_dynamic psd; | 203 struct pst_dynamic psd; |
81 if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0) | 204 if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0) |
82 && 0 <= pstat_getdynamic (&psd, sizeof psd, 1, 0)) | 205 && 0 <= pstat_getdynamic (&psd, sizeof psd, 1, 0)) |
83 { | 206 { |
87 return pages * pagesize; | 210 return pages * pagesize; |
88 } | 211 } |
89 } | 212 } |
90 #endif | 213 #endif |
91 | 214 |
215 #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE | |
216 { /* This works on irix6. */ | |
217 struct rminfo realmem; | |
218 if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0) | |
219 { | |
220 double pagesize = sysconf (_SC_PAGESIZE); | |
221 double pages = realmem.availrmem; | |
222 if (0 <= pages && 0 <= pagesize) | |
223 return pages * pagesize; | |
224 } | |
225 } | |
226 #endif | |
227 | |
228 #if HAVE_TABLE && defined TBL_VMSTATS | |
229 { /* This works on Tru64 UNIX V4/5. */ | |
230 struct tbl_vmstats vmstats; | |
231 | |
232 if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1) | |
233 { | |
234 double pages = vmstats.free_count; | |
235 double pagesize = vmstats.pagesize; | |
236 | |
237 if (0 <= pages && 0 <= pagesize) | |
238 return pages * pagesize; | |
239 } | |
240 } | |
241 #endif | |
242 | |
243 #if HAVE_SYSCTL && defined HW_USERMEM | |
244 { /* This works on *bsd and darwin. */ | |
245 unsigned int usermem; | |
246 size_t len = sizeof usermem; | |
247 static int mib[2] = { CTL_HW, HW_USERMEM }; | |
248 | |
249 if (sysctl (mib, ARRAY_SIZE (mib), &usermem, &len, NULL, 0) == 0 | |
250 && len == sizeof (usermem)) | |
251 return (double) usermem; | |
252 } | |
253 #endif | |
254 | |
255 #if defined _WIN32 | |
256 { /* this works on windows */ | |
257 PFN_MS_EX pfnex; | |
258 HMODULE h = GetModuleHandle ("kernel32.dll"); | |
259 | |
260 if (!h) | |
261 return 0.0; | |
262 | |
263 /* Use GlobalMemoryStatusEx if available. */ | |
264 if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx"))) | |
265 { | |
266 lMEMORYSTATUSEX lms_ex; | |
267 lms_ex.dwLength = sizeof lms_ex; | |
268 if (!pfnex (&lms_ex)) | |
269 return 0.0; | |
270 return (double) lms_ex.ullAvailPhys; | |
271 } | |
272 | |
273 /* Fall back to GlobalMemoryStatus which is always available. | |
274 but returns wrong results for physical memory > 4GB */ | |
275 else | |
276 { | |
277 MEMORYSTATUS ms; | |
278 GlobalMemoryStatus (&ms); | |
279 return (double) ms.dwAvailPhys; | |
280 } | |
281 } | |
282 #endif | |
283 | |
92 /* Guess 25% of physical memory. */ | 284 /* Guess 25% of physical memory. */ |
93 return physmem_total () / 4; | 285 return physmem_total () / 4; |
94 } | 286 } |
287 | |
288 | |
289 #if DEBUG | |
290 | |
291 # include <stdio.h> | |
292 # include <stdlib.h> | |
293 | |
294 int | |
295 main () | |
296 { | |
297 printf ("%12.f %12.f\n", physmem_total (), physmem_available ()); | |
298 exit (0); | |
299 } | |
300 | |
301 #endif /* DEBUG */ | |
302 | |
303 /* | |
304 Local Variables: | |
305 compile-command: "gcc -DDEBUG -DHAVE_CONFIG_H -I.. -g -O -Wall -W physmem.c" | |
306 End: | |
307 */ |