ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/utils/physmem.c
Revision: 3327
Committed: Wed Jan 23 21:23:15 2008 UTC (16 years, 5 months ago) by xsun
Content type: text/plain
File size: 7028 byte(s)
Log Message:
fixed bug in physmem for 64 bit machines

File Contents

# User Rev Content
1 tim 1996 /* Calculate the size of physical memory.
2    
3 xsun 3327 Copyright (C) 2000, 2001, 2003, 2005, 2006 Free Software
4     Foundation, Inc.
5    
6     This program is free software: you can redistribute it and/or modify
7 tim 1996 it under the terms of the GNU General Public License as published by
8 xsun 3327 the Free Software Foundation; either version 3 of the License, or
9     (at your option) any later version.
10 tim 1996
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 xsun 3327 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 tim 1996
19     /* Written by Paul Eggert. */
20    
21     #include "config.h"
22    
23 xsun 3327 #include "physmem.h"
24 tim 1996
25 xsun 3327 #include <unistd.h>
26    
27 tim 1996 #if HAVE_SYS_PSTAT_H
28     # include <sys/pstat.h>
29     #endif
30    
31     #if HAVE_SYS_SYSMP_H
32     # include <sys/sysmp.h>
33     #endif
34    
35     #if HAVE_SYS_SYSINFO_H && HAVE_MACHINE_HAL_SYSINFO_H
36     # include <sys/sysinfo.h>
37     # include <machine/hal_sysinfo.h>
38     #endif
39    
40     #if HAVE_SYS_TABLE_H
41     # include <sys/table.h>
42     #endif
43    
44     #include <sys/types.h>
45    
46     #if HAVE_SYS_PARAM_H
47     # include <sys/param.h>
48     #endif
49    
50     #if HAVE_SYS_SYSCTL_H
51     # include <sys/sysctl.h>
52     #endif
53    
54     #if HAVE_SYS_SYSTEMCFG_H
55     # include <sys/systemcfg.h>
56     #endif
57    
58     #ifdef _WIN32
59     # define WIN32_LEAN_AND_MEAN
60     # include <windows.h>
61     /* MEMORYSTATUSEX is missing from older windows headers, so define
62     a local replacement. */
63     typedef struct
64     {
65     DWORD dwLength;
66     DWORD dwMemoryLoad;
67     DWORDLONG ullTotalPhys;
68     DWORDLONG ullAvailPhys;
69     DWORDLONG ullTotalPageFile;
70     DWORDLONG ullAvailPageFile;
71     DWORDLONG ullTotalVirtual;
72     DWORDLONG ullAvailVirtual;
73     DWORDLONG ullAvailExtendedVirtual;
74     } lMEMORYSTATUSEX;
75     typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*);
76     #endif
77    
78 xsun 3327 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
79    
80 tim 1996 /* Return the total amount of physical memory. */
81 xsun 3327 double
82     physmem_total (void)
83 tim 1996 {
84     #if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE
85     { /* This works on linux-gnu, solaris2 and cygwin. */
86 xsun 3327 double pages = sysconf (_SC_PHYS_PAGES);
87     double pagesize = sysconf (_SC_PAGESIZE);
88 tim 1996 if (0 <= pages && 0 <= pagesize)
89     return pages * pagesize;
90     }
91     #endif
92    
93     #if HAVE_PSTAT_GETSTATIC
94     { /* This works on hpux11. */
95     struct pst_static pss;
96     if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0))
97     {
98 xsun 3327 double pages = pss.physical_memory;
99     double pagesize = pss.page_size;
100 tim 1996 if (0 <= pages && 0 <= pagesize)
101     return pages * pagesize;
102     }
103     }
104     #endif
105    
106     #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE
107     { /* This works on irix6. */
108     struct rminfo realmem;
109     if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0)
110     {
111 xsun 3327 double pagesize = sysconf (_SC_PAGESIZE);
112     double pages = realmem.physmem;
113 tim 1996 if (0 <= pages && 0 <= pagesize)
114     return pages * pagesize;
115     }
116     }
117     #endif
118    
119     #if HAVE_GETSYSINFO && defined GSI_PHYSMEM
120     { /* This works on Tru64 UNIX V4/5. */
121     int physmem;
122    
123     if (getsysinfo (GSI_PHYSMEM, (caddr_t) &physmem, sizeof (physmem),
124     NULL, NULL, NULL) == 1)
125     {
126 xsun 3327 double kbytes = physmem;
127 tim 1996
128     if (0 <= kbytes)
129     return kbytes * 1024.0;
130     }
131     }
132     #endif
133    
134     #if HAVE_SYSCTL && defined HW_PHYSMEM
135     { /* This works on *bsd and darwin. */
136     unsigned int physmem;
137     size_t len = sizeof physmem;
138     static int mib[2] = { CTL_HW, HW_PHYSMEM };
139    
140 xsun 3327 if (sysctl (mib, ARRAY_SIZE (mib), &physmem, &len, NULL, 0) == 0
141 tim 1996 && len == sizeof (physmem))
142 xsun 3327 return (double) physmem;
143 tim 1996 }
144     #endif
145    
146     #if HAVE__SYSTEM_CONFIGURATION
147     /* This works on AIX. */
148     return _system_configuration.physmem;
149     #endif
150    
151     #if defined _WIN32
152     { /* this works on windows */
153     PFN_MS_EX pfnex;
154     HMODULE h = GetModuleHandle ("kernel32.dll");
155    
156     if (!h)
157     return 0.0;
158    
159     /* Use GlobalMemoryStatusEx if available. */
160     if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
161     {
162     lMEMORYSTATUSEX lms_ex;
163     lms_ex.dwLength = sizeof lms_ex;
164     if (!pfnex (&lms_ex))
165     return 0.0;
166 xsun 3327 return (double) lms_ex.ullTotalPhys;
167 tim 1996 }
168    
169     /* Fall back to GlobalMemoryStatus which is always available.
170     but returns wrong results for physical memory > 4GB. */
171     else
172     {
173     MEMORYSTATUS ms;
174     GlobalMemoryStatus (&ms);
175 xsun 3327 return (double) ms.dwTotalPhys;
176 tim 1996 }
177     }
178     #endif
179    
180 xsun 3327 /* Guess 64 MB. It's probably an older host, so guess small. */
181     return 64 * 1024 * 1024;
182 tim 1996 }
183    
184     /* Return the amount of physical memory available. */
185 xsun 3327 double
186     physmem_available (void)
187 tim 1996 {
188     #if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE
189     { /* This works on linux-gnu, solaris2 and cygwin. */
190 xsun 3327 double pages = sysconf (_SC_AVPHYS_PAGES);
191     double pagesize = sysconf (_SC_PAGESIZE);
192 tim 1996 if (0 <= pages && 0 <= pagesize)
193     return pages * pagesize;
194     }
195     #endif
196    
197     #if HAVE_PSTAT_GETSTATIC && HAVE_PSTAT_GETDYNAMIC
198     { /* This works on hpux11. */
199     struct pst_static pss;
200     struct pst_dynamic psd;
201     if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0)
202     && 0 <= pstat_getdynamic (&psd, sizeof psd, 1, 0))
203     {
204 xsun 3327 double pages = psd.psd_free;
205     double pagesize = pss.page_size;
206 tim 1996 if (0 <= pages && 0 <= pagesize)
207     return pages * pagesize;
208     }
209     }
210     #endif
211    
212     #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE
213     { /* This works on irix6. */
214     struct rminfo realmem;
215     if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0)
216     {
217 xsun 3327 double pagesize = sysconf (_SC_PAGESIZE);
218     double pages = realmem.availrmem;
219 tim 1996 if (0 <= pages && 0 <= pagesize)
220     return pages * pagesize;
221     }
222     }
223     #endif
224    
225     #if HAVE_TABLE && defined TBL_VMSTATS
226     { /* This works on Tru64 UNIX V4/5. */
227     struct tbl_vmstats vmstats;
228    
229     if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1)
230     {
231 xsun 3327 double pages = vmstats.free_count;
232     double pagesize = vmstats.pagesize;
233 tim 1996
234     if (0 <= pages && 0 <= pagesize)
235     return pages * pagesize;
236     }
237     }
238     #endif
239    
240     #if HAVE_SYSCTL && defined HW_USERMEM
241     { /* This works on *bsd and darwin. */
242     unsigned int usermem;
243     size_t len = sizeof usermem;
244     static int mib[2] = { CTL_HW, HW_USERMEM };
245    
246 xsun 3327 if (sysctl (mib, ARRAY_SIZE (mib), &usermem, &len, NULL, 0) == 0
247 tim 1996 && len == sizeof (usermem))
248 xsun 3327 return (double) usermem;
249 tim 1996 }
250     #endif
251    
252     #if defined _WIN32
253     { /* this works on windows */
254     PFN_MS_EX pfnex;
255     HMODULE h = GetModuleHandle ("kernel32.dll");
256    
257     if (!h)
258     return 0.0;
259    
260     /* Use GlobalMemoryStatusEx if available. */
261     if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
262     {
263     lMEMORYSTATUSEX lms_ex;
264     lms_ex.dwLength = sizeof lms_ex;
265     if (!pfnex (&lms_ex))
266     return 0.0;
267 xsun 3327 return (double) lms_ex.ullAvailPhys;
268 tim 1996 }
269    
270     /* Fall back to GlobalMemoryStatus which is always available.
271     but returns wrong results for physical memory > 4GB */
272     else
273     {
274     MEMORYSTATUS ms;
275     GlobalMemoryStatus (&ms);
276 xsun 3327 return (double) ms.dwAvailPhys;
277 tim 1996 }
278     }
279     #endif
280    
281     /* Guess 25% of physical memory. */
282     return physmem_total () / 4;
283     }
284    

Properties

Name Value
svn:executable *