Fix masking of bits in serialised query
[xapian.git] / xapian-applications / omega / freemem.cc
blobf21c2a76417223e0d41da73146305208c5ddc596
1 /* freemem.cc: determine how much free physical memory there is.
3 * Copyright (C) 2007,2008,2009,2010 Olly Betts
4 * Copyright (C) 2008 Lemur Consulting Ltd
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
23 #include "freemem.h"
25 #include <sys/types.h>
26 #include <climits>
27 #include "safeunistd.h"
28 #ifdef HAVE_SYS_SYSCTL_H
29 # include <sys/sysctl.h>
30 #endif
31 #ifdef HAVE_VM_VM_PARAM_H
32 # include <vm/vm_param.h>
33 #endif
34 #ifdef HAVE_SYS_VMMETER_H
35 # include <sys/vmmeter.h>
36 #endif
37 #ifdef HAVE_SYS_SYSMP_H
38 # include <sys/sysmp.h>
39 #endif
40 #ifdef HAVE_SYS_SYSINFO_H
41 # include <sys/sysinfo.h>
42 #endif
43 #ifdef HAVE_SYS_PSTAT_H
44 # include <sys/pstat.h>
45 #endif
47 #ifdef __WIN32__
48 # include "safewindows.h"
49 #endif
51 /* Tested on:
52 * Linux, FreeBSD, IRIX, HP-UX, Microsoft Windows.
55 long
56 get_free_physical_memory()
58 #ifndef __WIN32__
59 long pagesize = 1;
60 long pages = -1;
61 #if defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
62 /* Linux:
63 * _SC_AVPHYS_PAGES is "available memory", but that excludes memory being
64 * used by the OS VM cache, which will often be almost all memory which
65 * isn't otherwise used, so used _SC_PHYS_PAGES which is just memory -
66 * that's good enough for Omega's use where we really just want to avoid
67 * runaway filter processes for dragging down the system.
69 pagesize = sysconf(_SC_PAGESIZE);
70 pages = sysconf(_SC_PHYS_PAGES);
71 #elif defined HAVE_SYSMP
72 /* IRIX: (rminfo64 and MPSA_RMINFO64?) */
73 struct rminfo meminfo;
74 if (sysmp(MP_SAGET, MPSA_RMINFO, &meminfo, sizeof(meminfo)) == 0) {
75 pagesize = sysconf(_SC_PAGESIZE);
76 pages = meminfo.availrmem;
78 #elif defined HAVE_PSTAT_GETDYNAMIC
79 /* HP-UX: */
80 struct pst_dynamic info;
81 if (pstat_getdynamic(&info, sizeof(info), 1, 0) == 1) {
82 pagesize = getpagesize();
83 pages = info.psd_free;
85 #elif defined CTL_VM && (defined VM_TOTAL || defined VM_METER)
86 /* FreeBSD: */
87 struct vmtotal vm_info;
88 int mib[2] = {
89 CTL_VM,
90 #ifdef VM_TOTAL
91 VM_TOTAL
92 #else
93 VM_METER
94 #endif
96 size_t len = sizeof(vm_info);
97 if (sysctl(mib, 2, &vm_info, &len, NULL, 0) == 0) {
98 pagesize = getpagesize();
99 pages = vm_info.t_free;
101 #endif
102 if (pagesize > 0 && pages > 0) {
103 long mem = LONG_MAX;
104 if (pages < LONG_MAX / pagesize) {
105 mem = pages * pagesize;
107 return mem;
109 return -1;
110 #else
111 MEMORYSTATUSEX statex;
112 statex.dwLength = sizeof(statex);
113 GlobalMemoryStatusEx(&statex);
114 return statex.ullAvailPhys;
115 #endif