• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************/
2 #ifdef JEMALLOC_H_TYPES
3 
4 /* Size of stack-allocated buffer passed to buferror(). */
5 #define	BUFERROR_BUF		64
6 
7 /*
8  * Size of stack-allocated buffer used by malloc_{,v,vc}printf().  This must be
9  * large enough for all possible uses within jemalloc.
10  */
11 #define	MALLOC_PRINTF_BUFSIZE	4096
12 
13 /*
14  * Wrap a cpp argument that contains commas such that it isn't broken up into
15  * multiple arguments.
16  */
17 #define	JEMALLOC_ARG_CONCAT(...) __VA_ARGS__
18 
19 /*
20  * Silence compiler warnings due to uninitialized values.  This is used
21  * wherever the compiler fails to recognize that the variable is never used
22  * uninitialized.
23  */
24 #ifdef JEMALLOC_CC_SILENCE
25 #	define JEMALLOC_CC_SILENCE_INIT(v) = v
26 #else
27 #	define JEMALLOC_CC_SILENCE_INIT(v)
28 #endif
29 
30 #ifdef __GNUC__
31 #	define likely(x)   __builtin_expect(!!(x), 1)
32 #	define unlikely(x) __builtin_expect(!!(x), 0)
33 #else
34 #	define likely(x)   !!(x)
35 #	define unlikely(x) !!(x)
36 #endif
37 
38 /*
39  * Define a custom assert() in order to reduce the chances of deadlock during
40  * assertion failure.
41  */
42 #ifndef assert
43 #define	assert(e) do {							\
44 	if (unlikely(config_debug && !(e))) {				\
45 		malloc_printf(						\
46 		    "<jemalloc>: %s:%d: Failed assertion: \"%s\"\n",	\
47 		    __FILE__, __LINE__, #e);				\
48 		abort();						\
49 	}								\
50 } while (0)
51 #endif
52 
53 #ifndef not_reached
54 #define	not_reached() do {						\
55 	if (config_debug) {						\
56 		malloc_printf(						\
57 		    "<jemalloc>: %s:%d: Unreachable code reached\n",	\
58 		    __FILE__, __LINE__);				\
59 		abort();						\
60 	}								\
61 } while (0)
62 #endif
63 
64 #ifndef not_implemented
65 #define	not_implemented() do {						\
66 	if (config_debug) {						\
67 		malloc_printf("<jemalloc>: %s:%d: Not implemented\n",	\
68 		    __FILE__, __LINE__);				\
69 		abort();						\
70 	}								\
71 } while (0)
72 #endif
73 
74 #ifndef assert_not_implemented
75 #define	assert_not_implemented(e) do {					\
76 	if (unlikely(config_debug && !(e)))				\
77 		not_implemented();					\
78 } while (0)
79 #endif
80 
81 /* Use to assert a particular configuration, e.g., cassert(config_debug). */
82 #define	cassert(c) do {							\
83 	if (unlikely(!(c)))						\
84 		not_reached();						\
85 } while (0)
86 
87 #endif /* JEMALLOC_H_TYPES */
88 /******************************************************************************/
89 #ifdef JEMALLOC_H_STRUCTS
90 
91 #endif /* JEMALLOC_H_STRUCTS */
92 /******************************************************************************/
93 #ifdef JEMALLOC_H_EXTERNS
94 
95 int	buferror(int err, char *buf, size_t buflen);
96 uintmax_t	malloc_strtoumax(const char *restrict nptr,
97     char **restrict endptr, int base);
98 void	malloc_write(const char *s);
99 
100 /*
101  * malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating
102  * point math.
103  */
104 int	malloc_vsnprintf(char *str, size_t size, const char *format,
105     va_list ap);
106 int	malloc_snprintf(char *str, size_t size, const char *format, ...)
107     JEMALLOC_ATTR(format(printf, 3, 4));
108 void	malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque,
109     const char *format, va_list ap);
110 void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
111     const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
112 void	malloc_printf(const char *format, ...)
113     JEMALLOC_ATTR(format(printf, 1, 2));
114 
115 #endif /* JEMALLOC_H_EXTERNS */
116 /******************************************************************************/
117 #ifdef JEMALLOC_H_INLINES
118 
119 #ifndef JEMALLOC_ENABLE_INLINE
120 int	jemalloc_ffsl(long bitmap);
121 int	jemalloc_ffs(int bitmap);
122 size_t	pow2_ceil(size_t x);
123 size_t	lg_floor(size_t x);
124 void	set_errno(int errnum);
125 int	get_errno(void);
126 #endif
127 
128 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_))
129 
130 /* Sanity check. */
131 #if !defined(JEMALLOC_INTERNAL_FFSL) || !defined(JEMALLOC_INTERNAL_FFS)
132 #  error Both JEMALLOC_INTERNAL_FFSL && JEMALLOC_INTERNAL_FFS should have been defined by configure
133 #endif
134 
135 JEMALLOC_ALWAYS_INLINE int
jemalloc_ffsl(long bitmap)136 jemalloc_ffsl(long bitmap)
137 {
138 
139 	return (JEMALLOC_INTERNAL_FFSL(bitmap));
140 }
141 
142 JEMALLOC_ALWAYS_INLINE int
jemalloc_ffs(int bitmap)143 jemalloc_ffs(int bitmap)
144 {
145 
146 	return (JEMALLOC_INTERNAL_FFS(bitmap));
147 }
148 
149 /* Compute the smallest power of 2 that is >= x. */
150 JEMALLOC_INLINE size_t
pow2_ceil(size_t x)151 pow2_ceil(size_t x)
152 {
153 
154 	x--;
155 	x |= x >> 1;
156 	x |= x >> 2;
157 	x |= x >> 4;
158 	x |= x >> 8;
159 	x |= x >> 16;
160 #if (LG_SIZEOF_PTR == 3)
161 	x |= x >> 32;
162 #endif
163 	x++;
164 	return (x);
165 }
166 
167 #if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
168 JEMALLOC_INLINE size_t
lg_floor(size_t x)169 lg_floor(size_t x)
170 {
171 	size_t ret;
172 
173 	assert(x != 0);
174 
175 	asm ("bsr %1, %0"
176 	    : "=r"(ret) // Outputs.
177 	    : "r"(x)    // Inputs.
178 	    );
179 	return (ret);
180 }
181 #elif (defined(_MSC_VER))
182 JEMALLOC_INLINE size_t
lg_floor(size_t x)183 lg_floor(size_t x)
184 {
185 	unsigned long ret;
186 
187 	assert(x != 0);
188 
189 #if (LG_SIZEOF_PTR == 3)
190 	_BitScanReverse64(&ret, x);
191 #elif (LG_SIZEOF_PTR == 2)
192 	_BitScanReverse(&ret, x);
193 #else
194 #  error "Unsupported type sizes for lg_floor()"
195 #endif
196 	return (ret);
197 }
198 #elif (defined(JEMALLOC_HAVE_BUILTIN_CLZ))
199 JEMALLOC_INLINE size_t
lg_floor(size_t x)200 lg_floor(size_t x)
201 {
202 
203 	assert(x != 0);
204 
205 #if (LG_SIZEOF_PTR == LG_SIZEOF_INT)
206 	return (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clz(x));
207 #elif (LG_SIZEOF_PTR == LG_SIZEOF_LONG)
208 	return (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clzl(x));
209 #else
210 #  error "Unsupported type sizes for lg_floor()"
211 #endif
212 }
213 #else
214 JEMALLOC_INLINE size_t
lg_floor(size_t x)215 lg_floor(size_t x)
216 {
217 
218 	assert(x != 0);
219 
220 	x |= (x >> 1);
221 	x |= (x >> 2);
222 	x |= (x >> 4);
223 	x |= (x >> 8);
224 	x |= (x >> 16);
225 #if (LG_SIZEOF_PTR == 3 && LG_SIZEOF_PTR == LG_SIZEOF_LONG)
226 	x |= (x >> 32);
227 	if (x == KZU(0xffffffffffffffff))
228 		return (63);
229 	x++;
230 	return (jemalloc_ffsl(x) - 2);
231 #elif (LG_SIZEOF_PTR == 2)
232 	if (x == KZU(0xffffffff))
233 		return (31);
234 	x++;
235 	return (jemalloc_ffs(x) - 2);
236 #else
237 #  error "Unsupported type sizes for lg_floor()"
238 #endif
239 }
240 #endif
241 
242 /* Set error code. */
243 JEMALLOC_INLINE void
set_errno(int errnum)244 set_errno(int errnum)
245 {
246 
247 #ifdef _WIN32
248 	SetLastError(errnum);
249 #else
250 	errno = errnum;
251 #endif
252 }
253 
254 /* Get last error code. */
255 JEMALLOC_INLINE int
get_errno(void)256 get_errno(void)
257 {
258 
259 #ifdef _WIN32
260 	return (GetLastError());
261 #else
262 	return (errno);
263 #endif
264 }
265 #endif
266 
267 #endif /* JEMALLOC_H_INLINES */
268 /******************************************************************************/
269