Improve random number generation
[wimlib] / include / wimlib / util.h
1 /*
2  * util.h - utility functions and macros
3  */
4 #ifndef _WIMLIB_UTIL_H
5 #define _WIMLIB_UTIL_H
6
7 #include "wimlib/compiler.h"
8 #include "wimlib/types.h"
9
10 /****************
11  * General macros
12  *****************/
13
14 /* Cast a pointer to a struct member to a pointer to the containing struct.  */
15 #define container_of(ptr, type, member) \
16         ((type *)((char *)(ptr) - offsetof(type, member)))
17
18 /* Calculate 'n / d', but round up instead of down.  */
19 #define DIV_ROUND_UP(n, d)      (((n) + (d) - 1) / (d))
20
21 /* Calculate 'n % d', but return 'd' if the result would be 0.  */
22 #define MODULO_NONZERO(n, d)    (((n) % (d)) ? ((n) % (d)) : (d))
23
24 /* Get the number of elements of an array type.  */
25 #define ARRAY_LEN(array)        (sizeof(array) / sizeof((array)[0]))
26
27 /* Round 'v' up to the next 'alignment'-byte aligned boundary.  'alignment' must
28  * be a power of 2.  */
29 #define ALIGN(v, alignment)     (((v) + ((alignment) - 1)) & ~((alignment) - 1))
30
31 /* Maximum number of bytes that can be allocated on the stack.
32  *
33  * Note: this isn't a hard bound on the stack space used, since this is just for
34  * individual arrays.  The full call stack could use more than this.  */
35 #define STACK_MAX 32768
36
37 /* Default size of file I/O buffer.  Currently assumed to be <= STACK_MAX.  */
38 #define BUFFER_SIZE 32768
39
40 /*******************
41  * Memory allocation
42  *******************/
43
44 extern void *
45 wimlib_malloc(size_t size) _malloc_attribute;
46
47 extern void
48 wimlib_free_memory(void *p);
49
50 extern void *
51 wimlib_realloc(void *ptr, size_t size);
52
53 extern void *
54 wimlib_calloc(size_t nmemb, size_t size) _malloc_attribute;
55
56 extern char *
57 wimlib_strdup(const char *str) _malloc_attribute;
58
59 #ifdef __WIN32__
60 extern wchar_t *
61 wimlib_wcsdup(const wchar_t *str) _malloc_attribute;
62 #endif
63
64 extern void *
65 wimlib_aligned_malloc(size_t size, size_t alignment) _malloc_attribute;
66
67 extern void
68 wimlib_aligned_free(void *ptr);
69
70 extern void *
71 memdup(const void *mem, size_t size) _malloc_attribute;
72
73 #define MALLOC          wimlib_malloc
74 #define FREE            wimlib_free_memory
75 #define REALLOC         wimlib_realloc
76 #define CALLOC          wimlib_calloc
77 #define STRDUP          wimlib_strdup
78 #define WCSDUP          wimlib_wcsdup
79 #define ALIGNED_MALLOC  wimlib_aligned_malloc
80 #define ALIGNED_FREE    wimlib_aligned_free
81
82 /*******************
83  * String utilities
84  *******************/
85
86 #ifndef HAVE_MEMPCPY
87 extern void *
88 mempcpy(void *dst, const void *src, size_t n);
89 #endif
90
91 /**************************
92  * Random number generation
93  **************************/
94
95 extern void
96 get_random_bytes(void *p, size_t n);
97
98 extern void
99 get_random_alnum_chars(tchar *p, size_t n);
100
101 /************************
102  * Hashing and comparison
103  ************************/
104
105 static inline bool
106 is_power_of_2(unsigned long n)
107 {
108         return (n != 0 && (n & (n - 1)) == 0);
109
110 }
111
112 static inline u64
113 hash_u64(u64 n)
114 {
115         return n * 0x9e37fffffffc0001ULL;
116 }
117
118 static inline int
119 cmp_u32(u32 n1, u32 n2)
120 {
121         if (n1 < n2)
122                 return -1;
123         if (n1 > n2)
124                 return 1;
125         return 0;
126 }
127
128 static inline int
129 cmp_u64(u64 n1, u64 n2)
130 {
131         if (n1 < n2)
132                 return -1;
133         if (n1 > n2)
134                 return 1;
135         return 0;
136 }
137
138 /************************
139  * System information
140  ************************/
141
142 unsigned
143 get_available_cpus(void);
144
145 u64
146 get_available_memory(void);
147
148 #endif /* _WIMLIB_UTIL_H */