40 |
|
#include <sys/sysctl.h> |
41 |
|
#include <unistd.h> |
42 |
|
#endif |
43 |
< |
#if defined(NETBSD) || defined(OPENBSD) |
43 |
> |
#if defined(NETBSD) |
44 |
|
#include <sys/param.h> |
45 |
|
#include <sys/time.h> |
46 |
|
#include <uvm/uvm.h> |
47 |
|
#endif |
48 |
+ |
#if defined(OPENBSD) |
49 |
+ |
#include <sys/param.h> |
50 |
+ |
#include <sys/types.h> |
51 |
+ |
#include <sys/sysctl.h> |
52 |
+ |
#include <sys/unistd.h> |
53 |
+ |
#endif |
54 |
+ |
#ifdef HPUX |
55 |
+ |
#include <sys/param.h> |
56 |
+ |
#include <sys/pstat.h> |
57 |
+ |
#include <unistd.h> |
58 |
+ |
#endif |
59 |
+ |
#ifdef WIN32 |
60 |
+ |
#include <windows.h> |
61 |
+ |
#include "win32.h" |
62 |
+ |
#endif |
63 |
|
|
64 |
|
sg_mem_stats *sg_get_mem_stats(){ |
65 |
|
|
66 |
|
static sg_mem_stats mem_stat; |
67 |
|
|
68 |
+ |
#ifdef HPUX |
69 |
+ |
struct pst_static *pstat_static; |
70 |
+ |
struct pst_dynamic pstat_dynamic; |
71 |
+ |
long long pagesize; |
72 |
+ |
#endif |
73 |
|
#ifdef SOLARIS |
74 |
|
kstat_ctl_t *kc; |
75 |
|
kstat_t *ksp; |
91 |
|
u_int inactive_count; |
92 |
|
int pagesize; |
93 |
|
#endif |
94 |
< |
#if defined(NETBSD) || defined(OPENBSD) |
94 |
> |
#if defined(NETBSD) |
95 |
|
struct uvmexp *uvm; |
96 |
|
#endif |
97 |
+ |
#if defined(OPENBSD) |
98 |
+ |
int mib[2]; |
99 |
+ |
struct vmtotal vmtotal; |
100 |
+ |
size_t size; |
101 |
+ |
int pagesize, page_multiplier; |
102 |
+ |
#endif |
103 |
+ |
#ifdef WIN32 |
104 |
+ |
MEMORYSTATUSEX memstats; |
105 |
+ |
#endif |
106 |
|
|
107 |
+ |
#ifdef HPUX |
108 |
+ |
if((pagesize=sysconf(_SC_PAGESIZE)) == -1){ |
109 |
+ |
sg_set_error_with_errno(SG_ERROR_SYSCONF, "_SC_PAGESIZE"); |
110 |
+ |
return NULL; |
111 |
+ |
} |
112 |
+ |
|
113 |
+ |
if (pstat_getdynamic(&pstat_dynamic, sizeof(pstat_dynamic), 1, 0) == -1) { |
114 |
+ |
sg_set_error_with_errno(SG_ERROR_PSTAT, "pstat_dynamic"); |
115 |
+ |
return NULL; |
116 |
+ |
} |
117 |
+ |
pstat_static = sg_get_pstat_static(); |
118 |
+ |
if (pstat_static == NULL) { |
119 |
+ |
return NULL; |
120 |
+ |
} |
121 |
+ |
|
122 |
+ |
/* FIXME Does this include swap? */ |
123 |
+ |
mem_stat.total = ((long long) pstat_static->physical_memory) * pagesize; |
124 |
+ |
mem_stat.free = ((long long) pstat_dynamic.psd_free) * pagesize; |
125 |
+ |
mem_stat.used = mem_stat.total - mem_stat.free; |
126 |
+ |
#endif |
127 |
|
#ifdef SOLARIS |
128 |
|
if((pagesize=sysconf(_SC_PAGESIZE)) == -1){ |
129 |
|
sg_set_error_with_errno(SG_ERROR_SYSCONF, "_SC_PAGESIZE"); |
230 |
|
mem_stat.used=physmem-mem_stat.free; |
231 |
|
#endif |
232 |
|
|
233 |
< |
#if defined(NETBSD) || defined(OPENBSD) |
233 |
> |
#if defined(NETBSD) |
234 |
|
if ((uvm = sg_get_uvmexp()) == NULL) { |
235 |
|
return NULL; |
236 |
|
} |
237 |
|
|
238 |
|
mem_stat.total = uvm->pagesize * uvm->npages; |
190 |
– |
#ifdef NETBSD |
239 |
|
mem_stat.cache = uvm->pagesize * (uvm->filepages + uvm->execpages); |
192 |
– |
#else |
193 |
– |
/* Can't find cache memory on OpenBSD */ |
194 |
– |
mem_stat.cache = 0; |
195 |
– |
#endif |
240 |
|
mem_stat.free = uvm->pagesize * (uvm->free + uvm->inactive); |
241 |
|
mem_stat.used = mem_stat.total - mem_stat.free; |
242 |
|
#endif |
243 |
|
|
244 |
+ |
#if defined(OPENBSD) |
245 |
+ |
/* The code in this section is based on the code in the OpenBSD |
246 |
+ |
* top utility, located at src/usr.bin/top/machine.c in the |
247 |
+ |
* OpenBSD source tree. |
248 |
+ |
* |
249 |
+ |
* For fun, and like OpenBSD top, we will do the multiplication |
250 |
+ |
* converting the memory stats in pages to bytes in base 2. |
251 |
+ |
*/ |
252 |
+ |
|
253 |
+ |
/* All memory stats in OpenBSD are returned as the number of pages. |
254 |
+ |
* To convert this into the number of bytes we need to know the |
255 |
+ |
* page size on this system. |
256 |
+ |
*/ |
257 |
+ |
pagesize = sysconf(_SC_PAGESIZE); |
258 |
+ |
|
259 |
+ |
/* The pagesize gives us the base 10 multiplier, so we need to work |
260 |
+ |
* out what the base 2 multiplier is. This means dividing |
261 |
+ |
* pagesize by 2 until we reach unity, and counting the number of |
262 |
+ |
* divisions required. |
263 |
+ |
*/ |
264 |
+ |
page_multiplier = 0; |
265 |
+ |
|
266 |
+ |
while (pagesize > 1) { |
267 |
+ |
page_multiplier++; |
268 |
+ |
pagesize >>= 1; |
269 |
+ |
} |
270 |
+ |
|
271 |
+ |
/* We can now ret the the raw VM stats (in pages) using the |
272 |
+ |
* sysctl interface. |
273 |
+ |
*/ |
274 |
+ |
mib[0] = CTL_VM; |
275 |
+ |
mib[1] = VM_METER; |
276 |
+ |
size = sizeof(vmtotal); |
277 |
+ |
|
278 |
+ |
if (sysctl(mib, 2, &vmtotal, &size, NULL, 0) < 0) { |
279 |
+ |
bzero(&vmtotal, sizeof(vmtotal)); |
280 |
+ |
sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_VM.VM_METER"); |
281 |
+ |
return NULL; |
282 |
+ |
} |
283 |
+ |
|
284 |
+ |
/* Convert the raw stats to bytes, and return these to the caller |
285 |
+ |
*/ |
286 |
+ |
mem_stat.used = (vmtotal.t_rm << page_multiplier); /* total real mem in use */ |
287 |
+ |
mem_stat.cache = 0; /* no cache stats */ |
288 |
+ |
mem_stat.free = (vmtotal.t_free << page_multiplier); /* free memory pages */ |
289 |
+ |
mem_stat.total = (mem_stat.used + mem_stat.free); |
290 |
+ |
#endif |
291 |
+ |
|
292 |
+ |
#ifdef WIN32 |
293 |
+ |
memstats.dwLength = sizeof(memstats); |
294 |
+ |
if (!GlobalMemoryStatusEx(&memstats)) { |
295 |
+ |
sg_set_error_with_errno(SG_ERROR_MEMSTATUS, NULL); |
296 |
+ |
return NULL; |
297 |
+ |
} |
298 |
+ |
mem_stat.free = memstats.ullAvailPhys; |
299 |
+ |
mem_stat.total = memstats.ullTotalPhys; |
300 |
+ |
mem_stat.used = mem_stat.total - mem_stat.free; |
301 |
+ |
if(read_counter_large(SG_WIN32_MEM_CACHE, &mem_stat.cache)) { |
302 |
+ |
mem_stat.cache = 0; |
303 |
+ |
} |
304 |
+ |
#endif |
305 |
|
return &mem_stat; |
306 |
|
} |