+/*
+ * util.h - utility functions and macros
+ */
#ifndef _WIMLIB_UTIL_H
#define _WIMLIB_UTIL_H
-#include "wimlib/types.h"
#include "wimlib/compiler.h"
+#include "wimlib/types.h"
-#include <stdio.h>
-#include <stddef.h>
+/****************
+ * General macros
+ *****************/
-#ifndef min
-#define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
- (__a < __b) ? __a : __b; })
-#endif
+/* Cast a pointer to a struct member to a pointer to the containing struct. */
+#define container_of(ptr, type, member) \
+ ((type *)((char *)(ptr) - offsetof(type, member)))
-#ifndef max
-#define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
- (__a > __b) ? __a : __b; })
-#endif
+/* Calculate 'n / d', but round up instead of down. */
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
-#ifndef swap
-#define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
-#endif
+/* Calculate 'n % d', but return 'd' if the result would be 0. */
+#define MODULO_NONZERO(n, d) (((n) % (d)) ? ((n) % (d)) : (d))
+
+/* Get the number of elements of an array type. */
+#define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
+
+/* Round 'v' up to the next 'alignment'-byte aligned boundary. 'alignment' must
+ * be a power of 2. */
+#define ALIGN(v, alignment) (((v) + ((alignment) - 1)) & ~((alignment) - 1))
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
+/* Maximum number of bytes that can be allocated on the stack.
*
- */
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
+ * Note: this isn't a hard bound on the stack space used, since this is just for
+ * individual arrays. The full call stack could use more than this. */
+#define STACK_MAX 32768
+
+/* Default size of file I/O buffer. Currently assumed to be <= STACK_MAX. */
+#define BUFFER_SIZE 32768
-#define DIV_ROUND_UP(numerator, denominator) \
- (((numerator) + (denominator) - 1) / (denominator))
+/*******************
+ * Memory allocation
+ *******************/
-#define MODULO_NONZERO(numerator, denominator) \
- (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
+extern void *
+wimlib_malloc(size_t size) _malloc_attribute;
-#define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
+extern void
+wimlib_free_memory(void *p);
-#define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
+extern void *
+wimlib_realloc(void *ptr, size_t size);
-/* Used for buffering FILE IO in a few places */
-#define BUFFER_SIZE 32768
+extern void *
+wimlib_calloc(size_t nmemb, size_t size) _malloc_attribute;
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+extern char *
+wimlib_strdup(const char *str) _malloc_attribute;
-#ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
-extern void *(*wimlib_malloc_func)(size_t);
-extern void (*wimlib_free_func)(void *);
-extern void *(*wimlib_realloc_func)(void *, size_t);
-extern void *wimlib_calloc(size_t nmemb, size_t size);
#ifdef __WIN32__
-extern wchar_t *wimlib_wcsdup(const wchar_t *str);
+extern wchar_t *
+wimlib_wcsdup(const wchar_t *str) _malloc_attribute;
#endif
-extern char *wimlib_strdup(const char *str);
-# define MALLOC wimlib_malloc_func
-# define FREE wimlib_free_func
-# define REALLOC wimlib_realloc_func
-# define CALLOC wimlib_calloc
-# define STRDUP wimlib_strdup
-# define WSTRDUP wimlib_wcsdup
-#else /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
-# include <stdlib.h>
-# include <string.h>
-# define MALLOC malloc
-# define FREE free
-# define REALLOC realloc
-# define CALLOC calloc
-# define STRDUP strdup
-# define WSTRDUP wcsdup
-#endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
-
-
-/* util.c */
+
+extern void *
+wimlib_aligned_malloc(size_t size, size_t alignment) _malloc_attribute;
+
extern void
-randomize_byte_array(u8 *p, size_t n);
+wimlib_aligned_free(void *ptr);
+
+extern void *
+memdup(const void *mem, size_t size) _malloc_attribute;
+
+#define MALLOC wimlib_malloc
+#define FREE wimlib_free_memory
+#define REALLOC wimlib_realloc
+#define CALLOC wimlib_calloc
+#define STRDUP wimlib_strdup
+#define WCSDUP wimlib_wcsdup
+#define ALIGNED_MALLOC wimlib_aligned_malloc
+#define ALIGNED_FREE wimlib_aligned_free
+
+/*******************
+ * String utilities
+ *******************/
+
+#ifndef HAVE_MEMPCPY
+extern void *
+mempcpy(void *dst, const void *src, size_t n);
+#endif
extern void
-randomize_char_array_with_alnum(tchar p[], size_t n);
+randomize_byte_array(u8 *p, size_t n);
extern void
-print_byte_field(const u8 field[], size_t len, FILE *out);
+randomize_char_array_with_alnum(tchar *p, size_t n);
+
+/************************
+ * Hashing and comparison
+ ************************/
-static inline u32
-bsr32(u32 n)
+static inline bool
+is_power_of_2(unsigned long n)
{
-#if defined(__x86__) || defined(__x86_64__)
- asm("bsrl %0, %0;"
- : "=r"(n)
- : "0" (n));
- return n;
-#else
- u32 pow = 0;
- while ((n >>= 1) != 0)
- pow++;
- return pow;
-#endif
+ return (n != 0 && (n & (n - 1)) == 0);
+
}
static inline u64
return n * 0x9e37fffffffc0001ULL;
}
+static inline int
+cmp_u32(u32 n1, u32 n2)
+{
+ if (n1 < n2)
+ return -1;
+ if (n1 > n2)
+ return 1;
+ return 0;
+}
+
+static inline int
+cmp_u64(u64 n1, u64 n2)
+{
+ if (n1 < n2)
+ return -1;
+ if (n1 > n2)
+ return 1;
+ return 0;
+}
+
+/************************
+ * System information
+ ************************/
+
+unsigned
+get_available_cpus(void);
+
+u64
+get_available_memory(void);
+
#endif /* _WIMLIB_UTIL_H */