2 * @brief determine how much free physical memory there is.
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
26 #include <sys/types.h>
28 #include "safeunistd.h"
29 #ifdef HAVE_SYS_SYSCTL_H
30 // Linux also has sys/sysctl.h but newer versions give a deprecation warning.
32 # include <sys/sysctl.h>
35 #ifdef HAVE_VM_VM_PARAM_H
36 # include <vm/vm_param.h>
38 #ifdef HAVE_SYS_VMMETER_H
39 # include <sys/vmmeter.h>
41 #ifdef HAVE_SYS_SYSMP_H
42 # include <sys/sysmp.h>
44 #ifdef HAVE_SYS_SYSINFO_H
45 # include <sys/sysinfo.h>
47 #ifdef HAVE_SYS_PSTAT_H
48 # include <sys/pstat.h>
52 # include "safewindows.h"
56 * Linux, FreeBSD, HP-UX, Microsoft Windows.
60 get_free_physical_memory()
65 #if defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
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
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)
84 struct vmtotal vm_info
;
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
;
99 if (pagesize
> 0 && pages
> 0) {
101 if (pages
< LONG_MAX
/ pagesize
) {
102 mem
= pages
* pagesize
;
108 MEMORYSTATUSEX statex
;
109 statex
.dwLength
= sizeof(statex
);
110 GlobalMemoryStatusEx(&statex
);
111 return statex
.ullAvailPhys
;