1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker *
3*61046927SAndroid Build Coastguard Worker * Copyright 2008-2010 VMware, Inc.
4*61046927SAndroid Build Coastguard Worker * All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the
8*61046927SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
9*61046927SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
10*61046927SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
11*61046927SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
12*61046927SAndroid Build Coastguard Worker * the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
15*61046927SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
16*61046927SAndroid Build Coastguard Worker * of the Software.
17*61046927SAndroid Build Coastguard Worker *
18*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*61046927SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21*61046927SAndroid Build Coastguard Worker * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22*61046927SAndroid Build Coastguard Worker * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23*61046927SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24*61046927SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*61046927SAndroid Build Coastguard Worker *
26*61046927SAndroid Build Coastguard Worker **************************************************************************/
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #include "hash_table.h"
30*61046927SAndroid Build Coastguard Worker #include "macros.h"
31*61046927SAndroid Build Coastguard Worker #include "os_misc.h"
32*61046927SAndroid Build Coastguard Worker #include "os_file.h"
33*61046927SAndroid Build Coastguard Worker #include "ralloc.h"
34*61046927SAndroid Build Coastguard Worker #include "simple_mtx.h"
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker #if DETECT_OS_WINDOWS
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker #include <windows.h>
42*61046927SAndroid Build Coastguard Worker #include <stdio.h>
43*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker #else
46*61046927SAndroid Build Coastguard Worker
47*61046927SAndroid Build Coastguard Worker #include <stdio.h>
48*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
49*61046927SAndroid Build Coastguard Worker #include <string.h>
50*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker #endif
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
56*61046927SAndroid Build Coastguard Worker # define LOG_TAG "MESA"
57*61046927SAndroid Build Coastguard Worker # include <unistd.h>
58*61046927SAndroid Build Coastguard Worker # include <log/log.h>
59*61046927SAndroid Build Coastguard Worker # include <cutils/properties.h>
60*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD || DETECT_OS_MANAGARM
61*61046927SAndroid Build Coastguard Worker # include <unistd.h>
62*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_OPENBSD || DETECT_OS_FREEBSD
63*61046927SAndroid Build Coastguard Worker # include <sys/resource.h>
64*61046927SAndroid Build Coastguard Worker # include <sys/sysctl.h>
65*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_APPLE || DETECT_OS_BSD
66*61046927SAndroid Build Coastguard Worker # include <sys/sysctl.h>
67*61046927SAndroid Build Coastguard Worker # if DETECT_OS_APPLE
68*61046927SAndroid Build Coastguard Worker # include <mach/mach_host.h>
69*61046927SAndroid Build Coastguard Worker # include <mach/vm_param.h>
70*61046927SAndroid Build Coastguard Worker # include <mach/vm_statistics.h>
71*61046927SAndroid Build Coastguard Worker # endif
72*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_HAIKU
73*61046927SAndroid Build Coastguard Worker # include <kernel/OS.h>
74*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_WINDOWS
75*61046927SAndroid Build Coastguard Worker # include <windows.h>
76*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_FUCHSIA
77*61046927SAndroid Build Coastguard Worker #include <unistd.h>
78*61046927SAndroid Build Coastguard Worker #include <zircon/syscalls.h>
79*61046927SAndroid Build Coastguard Worker #else
80*61046927SAndroid Build Coastguard Worker #error unexpected platform in os_sysinfo.c
81*61046927SAndroid Build Coastguard Worker #endif
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker void
os_log_message(const char * message)85*61046927SAndroid Build Coastguard Worker os_log_message(const char *message)
86*61046927SAndroid Build Coastguard Worker {
87*61046927SAndroid Build Coastguard Worker /* If the GALLIUM_LOG_FILE environment variable is set to a valid filename,
88*61046927SAndroid Build Coastguard Worker * write all messages to that file.
89*61046927SAndroid Build Coastguard Worker */
90*61046927SAndroid Build Coastguard Worker static FILE *fout = NULL;
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker if (!fout) {
93*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
94*61046927SAndroid Build Coastguard Worker /* one-time init */
95*61046927SAndroid Build Coastguard Worker const char *filename = os_get_option("GALLIUM_LOG_FILE");
96*61046927SAndroid Build Coastguard Worker if (filename) {
97*61046927SAndroid Build Coastguard Worker if (strcmp(filename, "stdout") == 0) {
98*61046927SAndroid Build Coastguard Worker fout = stdout;
99*61046927SAndroid Build Coastguard Worker } else {
100*61046927SAndroid Build Coastguard Worker const char *mode = "w";
101*61046927SAndroid Build Coastguard Worker if (filename[0] == '+') {
102*61046927SAndroid Build Coastguard Worker /* If the filename is prefixed with '+' then open the file for
103*61046927SAndroid Build Coastguard Worker * appending instead of normal writing.
104*61046927SAndroid Build Coastguard Worker */
105*61046927SAndroid Build Coastguard Worker mode = "a";
106*61046927SAndroid Build Coastguard Worker filename++; /* skip the '+' */
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker fout = fopen(filename, mode);
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker }
111*61046927SAndroid Build Coastguard Worker #endif
112*61046927SAndroid Build Coastguard Worker if (!fout)
113*61046927SAndroid Build Coastguard Worker fout = stderr;
114*61046927SAndroid Build Coastguard Worker }
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker #if DETECT_OS_WINDOWS
117*61046927SAndroid Build Coastguard Worker OutputDebugStringA(message);
118*61046927SAndroid Build Coastguard Worker #if !defined(_GAMING_XBOX)
119*61046927SAndroid Build Coastguard Worker if(GetConsoleWindow() && !IsDebuggerPresent()) {
120*61046927SAndroid Build Coastguard Worker fflush(stdout);
121*61046927SAndroid Build Coastguard Worker fputs(message, fout);
122*61046927SAndroid Build Coastguard Worker fflush(fout);
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker else if (fout != stderr) {
125*61046927SAndroid Build Coastguard Worker fputs(message, fout);
126*61046927SAndroid Build Coastguard Worker fflush(fout);
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker #endif
129*61046927SAndroid Build Coastguard Worker #else /* !DETECT_OS_WINDOWS */
130*61046927SAndroid Build Coastguard Worker fflush(stdout);
131*61046927SAndroid Build Coastguard Worker fputs(message, fout);
132*61046927SAndroid Build Coastguard Worker fflush(fout);
133*61046927SAndroid Build Coastguard Worker # if DETECT_OS_ANDROID
134*61046927SAndroid Build Coastguard Worker LOG_PRI(ANDROID_LOG_ERROR, LOG_TAG, "%s", message);
135*61046927SAndroid Build Coastguard Worker # endif
136*61046927SAndroid Build Coastguard Worker #endif
137*61046927SAndroid Build Coastguard Worker }
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
140*61046927SAndroid Build Coastguard Worker # include <ctype.h>
141*61046927SAndroid Build Coastguard Worker # include "c11/threads.h"
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker /**
144*61046927SAndroid Build Coastguard Worker * Get an option value from android's property system, as a fallback to
145*61046927SAndroid Build Coastguard Worker * getenv() (which is generally less useful on android due to processes
146*61046927SAndroid Build Coastguard Worker * typically being forked from the zygote.
147*61046927SAndroid Build Coastguard Worker *
148*61046927SAndroid Build Coastguard Worker * The option name used for getenv is translated into a property name
149*61046927SAndroid Build Coastguard Worker * by:
150*61046927SAndroid Build Coastguard Worker *
151*61046927SAndroid Build Coastguard Worker * 1) convert to lowercase
152*61046927SAndroid Build Coastguard Worker * 2) replace '_' with '.'
153*61046927SAndroid Build Coastguard Worker * 3) if necessary, prepend "mesa."
154*61046927SAndroid Build Coastguard Worker *
155*61046927SAndroid Build Coastguard Worker * For example:
156*61046927SAndroid Build Coastguard Worker * - MESA_EXTENSION_OVERRIDE -> mesa.extension.override
157*61046927SAndroid Build Coastguard Worker * - GALLIUM_HUD -> mesa.gallium.hud
158*61046927SAndroid Build Coastguard Worker *
159*61046927SAndroid Build Coastguard Worker */
160*61046927SAndroid Build Coastguard Worker static char *
os_get_android_option(const char * name)161*61046927SAndroid Build Coastguard Worker os_get_android_option(const char *name)
162*61046927SAndroid Build Coastguard Worker {
163*61046927SAndroid Build Coastguard Worker static thread_local char os_android_option_value[PROPERTY_VALUE_MAX];
164*61046927SAndroid Build Coastguard Worker char key[PROPERTY_KEY_MAX];
165*61046927SAndroid Build Coastguard Worker char *p = key, *end = key + PROPERTY_KEY_MAX;
166*61046927SAndroid Build Coastguard Worker /* add "mesa." prefix if necessary: */
167*61046927SAndroid Build Coastguard Worker if (strstr(name, "MESA_") != name)
168*61046927SAndroid Build Coastguard Worker p += strlcpy(p, "mesa.", end - p);
169*61046927SAndroid Build Coastguard Worker p += strlcpy(p, name, end - p);
170*61046927SAndroid Build Coastguard Worker for (int i = 0; key[i]; i++) {
171*61046927SAndroid Build Coastguard Worker if (key[i] == '_') {
172*61046927SAndroid Build Coastguard Worker key[i] = '.';
173*61046927SAndroid Build Coastguard Worker } else {
174*61046927SAndroid Build Coastguard Worker key[i] = tolower(key[i]);
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker }
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Worker int len = property_get(key, os_android_option_value, NULL);
179*61046927SAndroid Build Coastguard Worker if (len > 1) {
180*61046927SAndroid Build Coastguard Worker return os_android_option_value;
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker return NULL;
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker #endif
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker #if DETECT_OS_WINDOWS
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker /* getenv doesn't necessarily reflect changes to the environment
189*61046927SAndroid Build Coastguard Worker * that have been made during the process lifetime, if either the
190*61046927SAndroid Build Coastguard Worker * setter uses a different CRT (e.g. due to static linking) or the
191*61046927SAndroid Build Coastguard Worker * setter used the Win32 API directly. */
192*61046927SAndroid Build Coastguard Worker const char *
os_get_option(const char * name)193*61046927SAndroid Build Coastguard Worker os_get_option(const char *name)
194*61046927SAndroid Build Coastguard Worker {
195*61046927SAndroid Build Coastguard Worker static thread_local char value[_MAX_ENV];
196*61046927SAndroid Build Coastguard Worker DWORD size = GetEnvironmentVariableA(name, value, _MAX_ENV);
197*61046927SAndroid Build Coastguard Worker return (size > 0 && size < _MAX_ENV) ? value : NULL;
198*61046927SAndroid Build Coastguard Worker }
199*61046927SAndroid Build Coastguard Worker
200*61046927SAndroid Build Coastguard Worker #else
201*61046927SAndroid Build Coastguard Worker
202*61046927SAndroid Build Coastguard Worker const char *
os_get_option(const char * name)203*61046927SAndroid Build Coastguard Worker os_get_option(const char *name)
204*61046927SAndroid Build Coastguard Worker {
205*61046927SAndroid Build Coastguard Worker const char *opt = getenv(name);
206*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
207*61046927SAndroid Build Coastguard Worker if (!opt) {
208*61046927SAndroid Build Coastguard Worker opt = os_get_android_option(name);
209*61046927SAndroid Build Coastguard Worker }
210*61046927SAndroid Build Coastguard Worker #endif
211*61046927SAndroid Build Coastguard Worker return opt;
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker #endif
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker static struct hash_table *options_tbl;
217*61046927SAndroid Build Coastguard Worker static bool options_tbl_exited = false;
218*61046927SAndroid Build Coastguard Worker static simple_mtx_t options_tbl_mtx = SIMPLE_MTX_INITIALIZER;
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker /**
221*61046927SAndroid Build Coastguard Worker * NOTE: The strings that allocated with ralloc_strdup(options_tbl, ...)
222*61046927SAndroid Build Coastguard Worker * are freed by _mesa_hash_table_destroy automatically
223*61046927SAndroid Build Coastguard Worker */
224*61046927SAndroid Build Coastguard Worker static void
options_tbl_fini(void)225*61046927SAndroid Build Coastguard Worker options_tbl_fini(void)
226*61046927SAndroid Build Coastguard Worker {
227*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&options_tbl_mtx);
228*61046927SAndroid Build Coastguard Worker _mesa_hash_table_destroy(options_tbl, NULL);
229*61046927SAndroid Build Coastguard Worker options_tbl = NULL;
230*61046927SAndroid Build Coastguard Worker options_tbl_exited = true;
231*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&options_tbl_mtx);
232*61046927SAndroid Build Coastguard Worker }
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker const char *
os_get_option_cached(const char * name)235*61046927SAndroid Build Coastguard Worker os_get_option_cached(const char *name)
236*61046927SAndroid Build Coastguard Worker {
237*61046927SAndroid Build Coastguard Worker const char *opt = NULL;
238*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&options_tbl_mtx);
239*61046927SAndroid Build Coastguard Worker if (options_tbl_exited) {
240*61046927SAndroid Build Coastguard Worker opt = os_get_option(name);
241*61046927SAndroid Build Coastguard Worker goto exit_mutex;
242*61046927SAndroid Build Coastguard Worker }
243*61046927SAndroid Build Coastguard Worker
244*61046927SAndroid Build Coastguard Worker if (!options_tbl) {
245*61046927SAndroid Build Coastguard Worker options_tbl = _mesa_hash_table_create(NULL, _mesa_hash_string,
246*61046927SAndroid Build Coastguard Worker _mesa_key_string_equal);
247*61046927SAndroid Build Coastguard Worker if (options_tbl == NULL) {
248*61046927SAndroid Build Coastguard Worker goto exit_mutex;
249*61046927SAndroid Build Coastguard Worker }
250*61046927SAndroid Build Coastguard Worker atexit(options_tbl_fini);
251*61046927SAndroid Build Coastguard Worker }
252*61046927SAndroid Build Coastguard Worker struct hash_entry *entry = _mesa_hash_table_search(options_tbl, name);
253*61046927SAndroid Build Coastguard Worker if (entry) {
254*61046927SAndroid Build Coastguard Worker opt = entry->data;
255*61046927SAndroid Build Coastguard Worker goto exit_mutex;
256*61046927SAndroid Build Coastguard Worker }
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker char *name_dup = ralloc_strdup(options_tbl, name);
259*61046927SAndroid Build Coastguard Worker if (name_dup == NULL) {
260*61046927SAndroid Build Coastguard Worker goto exit_mutex;
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker opt = ralloc_strdup(options_tbl, os_get_option(name));
263*61046927SAndroid Build Coastguard Worker _mesa_hash_table_insert(options_tbl, name_dup, (void *)opt);
264*61046927SAndroid Build Coastguard Worker exit_mutex:
265*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&options_tbl_mtx);
266*61046927SAndroid Build Coastguard Worker return opt;
267*61046927SAndroid Build Coastguard Worker }
268*61046927SAndroid Build Coastguard Worker
269*61046927SAndroid Build Coastguard Worker /**
270*61046927SAndroid Build Coastguard Worker * Return the size of the total physical memory.
271*61046927SAndroid Build Coastguard Worker * \param size returns the size of the total physical memory
272*61046927SAndroid Build Coastguard Worker * \return true for success, or false on failure
273*61046927SAndroid Build Coastguard Worker */
274*61046927SAndroid Build Coastguard Worker bool
os_get_total_physical_memory(uint64_t * size)275*61046927SAndroid Build Coastguard Worker os_get_total_physical_memory(uint64_t *size)
276*61046927SAndroid Build Coastguard Worker {
277*61046927SAndroid Build Coastguard Worker #if DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD || DETECT_OS_MANAGARM
278*61046927SAndroid Build Coastguard Worker const long phys_pages = sysconf(_SC_PHYS_PAGES);
279*61046927SAndroid Build Coastguard Worker const long page_size = sysconf(_SC_PAGE_SIZE);
280*61046927SAndroid Build Coastguard Worker
281*61046927SAndroid Build Coastguard Worker if (phys_pages <= 0 || page_size <= 0)
282*61046927SAndroid Build Coastguard Worker return false;
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker *size = (uint64_t)phys_pages * (uint64_t)page_size;
285*61046927SAndroid Build Coastguard Worker return true;
286*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_APPLE || DETECT_OS_BSD
287*61046927SAndroid Build Coastguard Worker size_t len = sizeof(*size);
288*61046927SAndroid Build Coastguard Worker int mib[2];
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker mib[0] = CTL_HW;
291*61046927SAndroid Build Coastguard Worker #if DETECT_OS_APPLE
292*61046927SAndroid Build Coastguard Worker mib[1] = HW_MEMSIZE;
293*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_NETBSD || DETECT_OS_OPENBSD
294*61046927SAndroid Build Coastguard Worker mib[1] = HW_PHYSMEM64;
295*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_FREEBSD
296*61046927SAndroid Build Coastguard Worker mib[1] = HW_REALMEM;
297*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_DRAGONFLY
298*61046927SAndroid Build Coastguard Worker mib[1] = HW_PHYSMEM;
299*61046927SAndroid Build Coastguard Worker #else
300*61046927SAndroid Build Coastguard Worker #error Unsupported *BSD
301*61046927SAndroid Build Coastguard Worker #endif
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker return (sysctl(mib, 2, size, &len, NULL, 0) == 0);
304*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_HAIKU
305*61046927SAndroid Build Coastguard Worker system_info info;
306*61046927SAndroid Build Coastguard Worker status_t ret;
307*61046927SAndroid Build Coastguard Worker
308*61046927SAndroid Build Coastguard Worker ret = get_system_info(&info);
309*61046927SAndroid Build Coastguard Worker if (ret != B_OK || info.max_pages <= 0)
310*61046927SAndroid Build Coastguard Worker return false;
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker *size = (uint64_t)info.max_pages * (uint64_t)B_PAGE_SIZE;
313*61046927SAndroid Build Coastguard Worker return true;
314*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_WINDOWS
315*61046927SAndroid Build Coastguard Worker MEMORYSTATUSEX status;
316*61046927SAndroid Build Coastguard Worker BOOL ret;
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker status.dwLength = sizeof(status);
319*61046927SAndroid Build Coastguard Worker ret = GlobalMemoryStatusEx(&status);
320*61046927SAndroid Build Coastguard Worker *size = status.ullTotalPhys;
321*61046927SAndroid Build Coastguard Worker return (ret == true);
322*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_FUCHSIA
323*61046927SAndroid Build Coastguard Worker *size = zx_system_get_physmem();
324*61046927SAndroid Build Coastguard Worker return true;
325*61046927SAndroid Build Coastguard Worker #else
326*61046927SAndroid Build Coastguard Worker #error unexpected platform in os_misc.c
327*61046927SAndroid Build Coastguard Worker return false;
328*61046927SAndroid Build Coastguard Worker #endif
329*61046927SAndroid Build Coastguard Worker }
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker bool
os_get_available_system_memory(uint64_t * size)332*61046927SAndroid Build Coastguard Worker os_get_available_system_memory(uint64_t *size)
333*61046927SAndroid Build Coastguard Worker {
334*61046927SAndroid Build Coastguard Worker #if DETECT_OS_LINUX
335*61046927SAndroid Build Coastguard Worker char *meminfo = os_read_file("/proc/meminfo", NULL);
336*61046927SAndroid Build Coastguard Worker if (!meminfo)
337*61046927SAndroid Build Coastguard Worker return false;
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker char *str = strstr(meminfo, "MemAvailable:");
340*61046927SAndroid Build Coastguard Worker if (!str) {
341*61046927SAndroid Build Coastguard Worker free(meminfo);
342*61046927SAndroid Build Coastguard Worker return false;
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker uint64_t kb_mem_available;
346*61046927SAndroid Build Coastguard Worker if (sscanf(str, "MemAvailable: %" PRIu64, &kb_mem_available) == 1) {
347*61046927SAndroid Build Coastguard Worker free(meminfo);
348*61046927SAndroid Build Coastguard Worker *size = kb_mem_available << 10;
349*61046927SAndroid Build Coastguard Worker return true;
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker free(meminfo);
353*61046927SAndroid Build Coastguard Worker return false;
354*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_OPENBSD || DETECT_OS_FREEBSD
355*61046927SAndroid Build Coastguard Worker struct rlimit rl;
356*61046927SAndroid Build Coastguard Worker #if DETECT_OS_OPENBSD
357*61046927SAndroid Build Coastguard Worker int mib[] = { CTL_HW, HW_USERMEM64 };
358*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_FREEBSD
359*61046927SAndroid Build Coastguard Worker int mib[] = { CTL_HW, HW_USERMEM };
360*61046927SAndroid Build Coastguard Worker #endif
361*61046927SAndroid Build Coastguard Worker int64_t mem_available;
362*61046927SAndroid Build Coastguard Worker size_t len = sizeof(mem_available);
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker /* physmem - wired */
365*61046927SAndroid Build Coastguard Worker if (sysctl(mib, 2, &mem_available, &len, NULL, 0) == -1)
366*61046927SAndroid Build Coastguard Worker return false;
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker /* static login.conf limit */
369*61046927SAndroid Build Coastguard Worker if (getrlimit(RLIMIT_DATA, &rl) == -1)
370*61046927SAndroid Build Coastguard Worker return false;
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker *size = MIN2(mem_available, rl.rlim_cur);
373*61046927SAndroid Build Coastguard Worker return true;
374*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_WINDOWS
375*61046927SAndroid Build Coastguard Worker MEMORYSTATUSEX status;
376*61046927SAndroid Build Coastguard Worker BOOL ret;
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker status.dwLength = sizeof(status);
379*61046927SAndroid Build Coastguard Worker ret = GlobalMemoryStatusEx(&status);
380*61046927SAndroid Build Coastguard Worker *size = status.ullAvailPhys;
381*61046927SAndroid Build Coastguard Worker return (ret == true);
382*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_APPLE
383*61046927SAndroid Build Coastguard Worker vm_statistics64_data_t vm_stats;
384*61046927SAndroid Build Coastguard Worker mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
385*61046927SAndroid Build Coastguard Worker if (host_statistics64(mach_host_self(), HOST_VM_INFO,
386*61046927SAndroid Build Coastguard Worker (host_info64_t)&vm_stats, &count) != KERN_SUCCESS) {
387*61046927SAndroid Build Coastguard Worker return false;
388*61046927SAndroid Build Coastguard Worker }
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker *size = ((uint64_t)vm_stats.free_count + (uint64_t)vm_stats.inactive_count) * PAGE_SIZE;
391*61046927SAndroid Build Coastguard Worker return true;
392*61046927SAndroid Build Coastguard Worker #else
393*61046927SAndroid Build Coastguard Worker return false;
394*61046927SAndroid Build Coastguard Worker #endif
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker /**
398*61046927SAndroid Build Coastguard Worker * Return the size of a page
399*61046927SAndroid Build Coastguard Worker * \param size returns the size of a page
400*61046927SAndroid Build Coastguard Worker * \return true for success, or false on failure
401*61046927SAndroid Build Coastguard Worker */
402*61046927SAndroid Build Coastguard Worker bool
os_get_page_size(uint64_t * size)403*61046927SAndroid Build Coastguard Worker os_get_page_size(uint64_t *size)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker #if DETECT_OS_POSIX_LITE && !DETECT_OS_APPLE && !DETECT_OS_HAIKU
406*61046927SAndroid Build Coastguard Worker const long page_size = sysconf(_SC_PAGE_SIZE);
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker if (page_size <= 0)
409*61046927SAndroid Build Coastguard Worker return false;
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker *size = (uint64_t)page_size;
412*61046927SAndroid Build Coastguard Worker return true;
413*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_HAIKU
414*61046927SAndroid Build Coastguard Worker *size = (uint64_t)B_PAGE_SIZE;
415*61046927SAndroid Build Coastguard Worker return true;
416*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_WINDOWS
417*61046927SAndroid Build Coastguard Worker SYSTEM_INFO SysInfo;
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker GetSystemInfo(&SysInfo);
420*61046927SAndroid Build Coastguard Worker *size = SysInfo.dwPageSize;
421*61046927SAndroid Build Coastguard Worker return true;
422*61046927SAndroid Build Coastguard Worker #elif DETECT_OS_APPLE
423*61046927SAndroid Build Coastguard Worker *size = PAGE_SIZE;
424*61046927SAndroid Build Coastguard Worker return true;
425*61046927SAndroid Build Coastguard Worker #else
426*61046927SAndroid Build Coastguard Worker #error unexpected platform in os_sysinfo.c
427*61046927SAndroid Build Coastguard Worker return false;
428*61046927SAndroid Build Coastguard Worker #endif
429*61046927SAndroid Build Coastguard Worker }
430