xapian-core  1.4.21
freemem.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2007,2008,2009,2010,2020 Olly Betts
5  * Copyright (C) 2008 Lemur Consulting Ltd
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 #include <config.h>
23 
24 #include "freemem.h"
25 
26 #include <sys/types.h>
27 #include "safeunistd.h"
28 #ifdef HAVE_SYS_SYSCTL_H
29 // Linux also has sys/sysctl.h but newer versions give a deprecation warning.
30 # ifndef __linux__
31 # include <sys/sysctl.h>
32 # endif
33 #endif
34 #ifdef HAVE_VM_VM_PARAM_H
35 # include <vm/vm_param.h>
36 #endif
37 #ifdef HAVE_SYS_VMMETER_H
38 # include <sys/vmmeter.h>
39 #endif
40 #ifdef HAVE_SYS_SYSMP_H
41 # include <sys/sysmp.h>
42 #endif
43 #ifdef HAVE_SYS_SYSINFO_H
44 # include <sys/sysinfo.h>
45 #endif
46 #ifdef HAVE_SYS_PSTAT_H
47 # include <sys/pstat.h>
48 #endif
49 
50 #ifdef __WIN32__
51 # include "safewindows.h"
52 #endif
53 
54 /* Tested on:
55  * Linux, FreeBSD, IRIX, HP-UX, Microsoft Windows.
56  */
57 
58 long long
60 {
61 #ifndef __WIN32__
62  long long pagesize = 1;
63  long long pages = -1;
64 #if defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
65  /* Linux:
66  * _SC_AVPHYS_PAGES is "available memory", but that excludes memory being
67  * used by the OS VM cache, which will often be almost all memory which
68  * isn't otherwise used, so used _SC_PHYS_PAGES which is just memory -
69  * that's good enough for Omega's use where we really just want to avoid
70  * runaway filter processes for dragging down the system.
71  */
72  pagesize = sysconf(_SC_PAGESIZE);
73  pages = sysconf(_SC_PHYS_PAGES);
74 #elif defined HAVE_SYSMP
75  /* IRIX: (rminfo64 and MPSA_RMINFO64?) */
76  struct rminfo meminfo;
77  if (sysmp(MP_SAGET, MPSA_RMINFO, &meminfo, sizeof(meminfo)) == 0) {
78  pagesize = sysconf(_SC_PAGESIZE);
79  pages = meminfo.availrmem;
80  }
81 #elif defined HAVE_PSTAT_GETDYNAMIC
82  /* HP-UX: */
83  struct pst_dynamic info;
84  if (pstat_getdynamic(&info, sizeof(info), 1, 0) == 1) {
85  pagesize = getpagesize();
86  pages = info.psd_free;
87  }
88 #elif defined CTL_VM && (defined VM_TOTAL || defined VM_METER)
89  /* FreeBSD: */
90  struct vmtotal vm_info;
91  static const int mib[2] = {
92  CTL_VM,
93 #ifdef VM_TOTAL
94  VM_TOTAL
95 #else
96  VM_METER
97 #endif
98  };
99  size_t len = sizeof(vm_info);
100  if (sysctl(mib, 2, &vm_info, &len, NULL, 0) == 0) {
101  pagesize = getpagesize();
102  pages = vm_info.t_free;
103  }
104 #endif
105  if (pagesize > 0 && pages > 0) {
106  return pages * pagesize;
107  }
108  return -1;
109 #else
110  MEMORYSTATUSEX statex;
111  statex.dwLength = sizeof(statex);
112  GlobalMemoryStatusEx(&statex);
113  return statex.ullAvailPhys;
114 #endif
115 }
116 
117 /* Tested on:
118  * Linux, Microsoft Windows.
119  */
120 
121 long long
123 {
124 #ifndef __WIN32__
125  long long pagesize = 1;
126  long long pages = -1;
127 #if defined(_SC_PAGESIZE) && defined(_SC_AVPHYS_PAGES)
128  /* Linux: */
129  pagesize = sysconf(_SC_PAGESIZE);
130  pages = sysconf(_SC_PHYS_PAGES);
131 #elif defined HAVE_SYSMP
132  /* IRIX: (rminfo64 and MPSA_RMINFO64?) */
133  struct rminfo meminfo;
134  if (sysmp(MP_SAGET, MPSA_RMINFO, &meminfo, sizeof(meminfo)) == 0) {
135  pagesize = sysconf(_SC_PAGESIZE);
136  pages = meminfo.physmem;
137  }
138 #elif defined HAVE_PSTAT_GETDYNAMIC
139  /* HP-UX: */
140  struct pst_dynamic info;
141  if (pstat_getdynamic(&info, sizeof(info), 1, 0) == 1) {
142  pagesize = getpagesize();
143  pages = info.psd_rm;
144  }
145 #elif defined CTL_VM && (defined VM_TOTAL || defined VM_METER)
146  /* FreeBSD: */
147  struct vmtotal vm_info;
148  static const int mib[2] = {
149  CTL_VM,
150 #ifdef VM_TOTAL
151  VM_TOTAL
152 #else
153  VM_METER
154 #endif
155  };
156  size_t len = sizeof(vm_info);
157  if (sysctl(mib, 2, &vm_info, &len, NULL, 0) == 0) {
158  pagesize = getpagesize();
159  pages = vm_info.t_rm;
160  }
161 #endif
162  if (pagesize > 0 && pages > 0) {
163  return pages * pagesize;
164  }
165  return -1;
166 #else
167  MEMORYSTATUSEX statex;
168  statex.dwLength = sizeof(statex);
169  GlobalMemoryStatusEx(&statex);
170  return statex.ullTotalPhys;
171 #endif
172 }
long long get_total_physical_memory()
Determine how much physical memory there is.
Definition: freemem.cc:122
include <windows.h> without all the bloat and damage.
<unistd.h>, but with compat.
determine how much free physical memory there is.
long long get_free_physical_memory()
Determine how much free physical memory there is.
Definition: freemem.cc:59