X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib%2Futil.h;h=c3bac7abe46be8d0c55f105989f318860e78dd8a;hp=177e1190f94a029df32a05e2eb4758a509b2a113;hb=f50557a7095444c554a066b3837c2999ecd1be31;hpb=e8c3ca2d1d0cac3d64985b45a9f654d2029a7518 diff --git a/include/wimlib/util.h b/include/wimlib/util.h index 177e1190..c3bac7ab 100644 --- a/include/wimlib/util.h +++ b/include/wimlib/util.h @@ -1,105 +1,108 @@ +/* + * 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 -#include +/**************** + * 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])) -/** - * 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. +/* 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)) + +/* 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 -#define DIV_ROUND_UP(numerator, denominator) \ - (((numerator) + (denominator) - 1) / (denominator)) +/* Default size of file I/O buffer. Currently assumed to be <= STACK_MAX. */ +#define BUFFER_SIZE 32768 -#define MODULO_NONZERO(numerator, denominator) \ - (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator)) +/******************* + * Memory allocation + *******************/ -#define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0])) +extern void * +wimlib_malloc(size_t size) _malloc_attribute; -#define ZERO_ARRAY(array) memset(array, 0, sizeof(array)) +extern void +wimlib_free_memory(void *p); -/* Used for buffering FILE IO in a few places */ -#define BUFFER_SIZE 32768 +extern void * +wimlib_realloc(void *ptr, size_t size); + +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 -# include -# 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 @@ -108,4 +111,24 @@ hash_u64(u64 n) return n * 0x9e37fffffffc0001ULL; } +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 */