2 * util.c - utility functions
6 * Copyright (C) 2012-2016 Eric Biggers
8 * This file is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License as published by the Free
10 * Software Foundation; either version 3 of the License, or (at your option) any
13 * This file is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this file; if not, see http://www.gnu.org/licenses/.
31 #ifdef HAVE_SYS_SYSCTL_H
32 # include <sys/types.h>
33 # include <sys/sysctl.h>
38 #include "wimlib/assert.h"
39 #include "wimlib/error.h"
40 #include "wimlib/timestamp.h"
41 #include "wimlib/util.h"
42 #include "wimlib/xml.h"
48 static void *(*wimlib_malloc_func) (size_t) = malloc;
49 static void (*wimlib_free_func) (void *) = free;
50 static void *(*wimlib_realloc_func)(void *, size_t) = realloc;
53 wimlib_malloc(size_t size)
58 ptr = (*wimlib_malloc_func)(size);
69 wimlib_free_memory(void *ptr)
71 (*wimlib_free_func)(ptr);
75 wimlib_realloc(void *ptr, size_t size)
79 return (*wimlib_realloc_func)(ptr, size);
83 wimlib_calloc(size_t nmemb, size_t size)
85 size_t total_size = nmemb * size;
88 if (size != 0 && nmemb > SIZE_MAX / size) {
93 p = MALLOC(total_size);
95 p = memset(p, 0, total_size);
100 wimlib_strdup(const char *str)
102 return memdup(str, strlen(str) + 1);
107 wimlib_wcsdup(const wchar_t *str)
109 return memdup(str, (wcslen(str) + 1) * sizeof(wchar_t));
114 wimlib_aligned_malloc(size_t size, size_t alignment)
116 wimlib_assert(is_power_of_2(alignment));
118 void *ptr = MALLOC(sizeof(void *) + alignment - 1 + size);
120 void *orig_ptr = ptr;
121 ptr = (void *)ALIGN((uintptr_t)ptr + sizeof(void *), alignment);
122 ((void **)ptr)[-1] = orig_ptr;
128 wimlib_aligned_free(void *ptr)
131 FREE(((void **)ptr)[-1]);
135 memdup(const void *mem, size_t size)
137 void *ptr = MALLOC(size);
139 ptr = memcpy(ptr, mem, size);
143 /* API function documented in wimlib.h */
145 wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
146 void (*free_func)(void *),
147 void *(*realloc_func)(void *, size_t))
149 wimlib_malloc_func = malloc_func ? malloc_func : malloc;
150 wimlib_free_func = free_func ? free_func : free;
151 wimlib_realloc_func = realloc_func ? realloc_func : realloc;
153 xml_set_memory_allocator(wimlib_malloc_func, wimlib_free_func,
154 wimlib_realloc_func);
163 void *mempcpy(void *dst, const void *src, size_t n)
165 return memcpy(dst, src, n) + n;
169 static bool seeded = false;
174 srand(now_as_wim_timestamp());
178 /* Fills @n characters pointed to by @p with random alphanumeric characters. */
180 randomize_char_array_with_alnum(tchar *p, size_t n)
195 /* Fills @n bytes pointer to by @p with random numbers. */
197 randomize_byte_array(u8 *p, size_t n)
207 get_available_cpus(void)
209 long n = sysconf(_SC_NPROCESSORS_ONLN);
210 if (n < 1 || n >= UINT_MAX) {
211 WARNING("Failed to determine number of processors; assuming 1.");
216 #endif /* !__WIN32__ */
220 get_available_memory(void)
222 #if defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
223 long page_size = sysconf(_SC_PAGESIZE);
224 long num_pages = sysconf(_SC_PHYS_PAGES);
225 if (page_size <= 0 || num_pages <= 0)
227 return ((u64)page_size * (u64)num_pages);
229 int mib[2] = {CTL_HW, HW_MEMSIZE};
231 size_t len = sizeof(memsize);
232 if (sysctl(mib, ARRAY_LEN(mib), &memsize, &len, NULL, 0) < 0 || len != 8)
238 WARNING("Failed to determine available memory; assuming 1 GiB");
241 #endif /* !__WIN32__ */