]> wimlib.net Git - wimlib/blobdiff - src/util.c
util.c: for aligned_malloc, store original pointer directly
[wimlib] / src / util.c
index 8d841cc173c9d82ecd24b196123130b537c9eed7..e0c5cc1bbc94ec0421bfd6184ee4834495c6f1e0 100644 (file)
 #  include "config.h"
 #endif
 
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef HAVE_SYS_SYSCTL_H
+#  include <sys/types.h>
+#  include <sys/sysctl.h>
+#endif
+#include <unistd.h>
 
 #include "wimlib.h"
 #include "wimlib/assert.h"
+#include "wimlib/error.h"
 #include "wimlib/timestamp.h"
 #include "wimlib/util.h"
 #include "wimlib/xml.h"
@@ -84,51 +91,28 @@ wimlib_calloc(size_t nmemb, size_t size)
 char *
 wimlib_strdup(const char *str)
 {
-       size_t size;
-       char *p;
-
-       size = strlen(str);
-       p = MALLOC(size + 1);
-       if (p)
-               p = memcpy(p, str, size + 1);
-       return p;
+       return memdup(str, strlen(str) + 1);
 }
 
 #ifdef __WIN32__
 wchar_t *
 wimlib_wcsdup(const wchar_t *str)
 {
-       size_t size;
-       wchar_t *p;
-
-       size = wcslen(str);
-       p = MALLOC((size + 1) * sizeof(wchar_t));
-       if (p)
-               p = wmemcpy(p, str, size + 1);
-       return p;
+       return memdup(str, (wcslen(str) + 1) * sizeof(wchar_t));
 }
 #endif
 
 void *
 wimlib_aligned_malloc(size_t size, size_t alignment)
 {
-       u8 *raw_ptr;
-       u8 *ptr;
-       uintptr_t mask;
-
-       wimlib_assert(alignment != 0 && is_power_of_2(alignment) &&
-                     alignment <= 4096);
-       mask = alignment - 1;
-
-       raw_ptr = MALLOC(size + alignment - 1 + sizeof(size_t));
-       if (!raw_ptr)
-               return NULL;
-
-       ptr = (u8 *)raw_ptr + sizeof(size_t);
-       while ((uintptr_t)ptr & mask)
-               ptr++;
-       *((size_t *)ptr - 1) = (ptr - raw_ptr);
+       wimlib_assert(is_power_of_2(alignment));
 
+       void *ptr = MALLOC(sizeof(void *) + alignment - 1 + size);
+       if (ptr) {
+               void *orig_ptr = ptr;
+               ptr = (void *)ALIGN((uintptr_t)ptr + sizeof(void *), alignment);
+               ((void **)ptr)[-1] = orig_ptr;
+       }
        return ptr;
 }
 
@@ -136,7 +120,7 @@ void
 wimlib_aligned_free(void *ptr)
 {
        if (ptr)
-               FREE((u8 *)ptr - *((size_t *)ptr - 1));
+               FREE(((void **)ptr)[-1]);
 }
 
 void *
@@ -174,15 +158,6 @@ void *mempcpy(void *dst, const void *src, size_t n)
 }
 #endif
 
-size_t
-utf16le_strlen(const utf16lechar *s)
-{
-       const utf16lechar *p = s;
-       while (*p)
-               p++;
-       return (p - s) * sizeof(utf16lechar);
-}
-
 static bool seeded = false;
 
 static void
@@ -218,3 +193,41 @@ randomize_byte_array(u8 *p, size_t n)
        while (n--)
                *p++ = rand();
 }
+
+#ifndef __WIN32__
+unsigned
+get_available_cpus(void)
+{
+       long n = sysconf(_SC_NPROCESSORS_ONLN);
+       if (n < 1 || n >= UINT_MAX) {
+               WARNING("Failed to determine number of processors; assuming 1.");
+               return 1;
+       }
+       return n;
+}
+#endif /* !__WIN32__ */
+
+#ifndef __WIN32__
+u64
+get_available_memory(void)
+{
+#if defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
+       long page_size = sysconf(_SC_PAGESIZE);
+       long num_pages = sysconf(_SC_PHYS_PAGES);
+       if (page_size <= 0 || num_pages <= 0)
+               goto default_size;
+       return ((u64)page_size * (u64)num_pages);
+#else
+       int mib[2] = {CTL_HW, HW_MEMSIZE};
+       u64 memsize;
+       size_t len = sizeof(memsize);
+       if (sysctl(mib, ARRAY_LEN(mib), &memsize, &len, NULL, 0) < 0 || len != 8)
+               goto default_size;
+       return memsize;
+#endif
+
+default_size:
+       WARNING("Failed to determine available memory; assuming 1 GiB");
+       return (u64)1 << 30;
+}
+#endif /* !__WIN32__ */