ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/utils/physmem.c
Revision: 1996
Committed: Fri Feb 11 22:35:05 2005 UTC (19 years, 4 months ago) by tim
Content type: text/plain
File size: 6941 byte(s)
Log Message:
adding physmem

File Contents

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

Properties

Name Value
svn:executable *