[ci] Test Tcl bindings for dragonfly/freebsd
[xapian.git] / xapian-applications / omega / freemem.cc
blob1b4e711230eae06324e39cca8e0f385a9aa88ed7
1 /** @file
2 * @brief determine how much free physical memory there is.
3 */
4 /* Copyright (C) 2007,2008,2009,2010,2020 Olly Betts
5 * Copyright (C) 2008 Lemur Consulting Ltd
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <config.h>
24 #include "freemem.h"
26 #include <sys/types.h>
27 #include <climits>
28 #include "safeunistd.h"
29 #ifdef HAVE_SYS_SYSCTL_H
30 // Linux also has sys/sysctl.h but newer versions give a deprecation warning.
31 # ifndef __linux__
32 # include <sys/sysctl.h>
33 # endif
34 #endif
35 #ifdef HAVE_VM_VM_PARAM_H
36 # include <vm/vm_param.h>
37 #endif
38 #ifdef HAVE_SYS_VMMETER_H
39 # include <sys/vmmeter.h>
40 #endif
41 #ifdef HAVE_SYS_SYSMP_H
42 # include <sys/sysmp.h>
43 #endif
44 #ifdef HAVE_SYS_SYSINFO_H
45 # include <sys/sysinfo.h>
46 #endif
47 #ifdef HAVE_SYS_PSTAT_H
48 # include <sys/pstat.h>
49 #endif
51 #ifdef __WIN32__
52 # include "safewindows.h"
53 #endif
55 /* Tested on:
56 * Linux, FreeBSD, HP-UX, Microsoft Windows.
59 long
60 get_free_physical_memory()
62 #ifndef __WIN32__
63 long pagesize = 1;
64 long pages = -1;
65 #if defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
66 /* Linux:
67 * _SC_AVPHYS_PAGES is "available memory", but that excludes memory being
68 * used by the OS VM cache, which will often be almost all memory which
69 * isn't otherwise used, so used _SC_PHYS_PAGES which is just memory -
70 * that's good enough for Omega's use where we really just want to avoid
71 * runaway filter processes for dragging down the system.
73 pagesize = sysconf(_SC_PAGESIZE);
74 pages = sysconf(_SC_PHYS_PAGES);
75 #elif defined HAVE_PSTAT_GETDYNAMIC
76 /* HP-UX: */
77 struct pst_dynamic info;
78 if (pstat_getdynamic(&info, sizeof(info), 1, 0) == 1) {
79 pagesize = getpagesize();
80 pages = info.psd_free;
82 #elif defined CTL_VM && (defined VM_TOTAL || defined VM_METER)
83 /* FreeBSD: */
84 struct vmtotal vm_info;
85 int mib[2] = {
86 CTL_VM,
87 #ifdef VM_TOTAL
88 VM_TOTAL
89 #else
90 VM_METER
91 #endif
93 size_t len = sizeof(vm_info);
94 if (sysctl(mib, 2, &vm_info, &len, NULL, 0) == 0) {
95 pagesize = getpagesize();
96 pages = vm_info.t_free;
98 #endif
99 if (pagesize > 0 && pages > 0) {
100 long mem = LONG_MAX;
101 if (pages < LONG_MAX / pagesize) {
102 mem = pages * pagesize;
104 return mem;
106 return -1;
107 #else
108 MEMORYSTATUSEX statex;
109 statex.dwLength = sizeof(statex);
110 GlobalMemoryStatusEx(&statex);
111 return statex.ullAvailPhys;
112 #endif