util.h revision 8d8f9aeeaa77514d5732db5bd0111232af21fcfd
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/*
31 * Define a custom assert() in order to reduce the chances of deadlock during
32 * assertion failure.
33 */
34#ifndef assert
35#define	assert(e) do {							\
36	if (config_debug && !(e)) {					\
37		malloc_printf(						\
38		    "<jemalloc>: %s:%d: Failed assertion: \"%s\"\n",	\
39		    __FILE__, __LINE__, #e);				\
40		abort();						\
41	}								\
42} while (0)
43#endif
44
45#ifndef not_reached
46#define	not_reached() do {						\
47	if (config_debug) {						\
48		malloc_printf(						\
49		    "<jemalloc>: %s:%d: Unreachable code reached\n",	\
50		    __FILE__, __LINE__);				\
51		abort();						\
52	}								\
53} while (0)
54#endif
55
56#ifndef not_implemented
57#define	not_implemented() do {						\
58	if (config_debug) {						\
59		malloc_printf("<jemalloc>: %s:%d: Not implemented\n",	\
60		    __FILE__, __LINE__);				\
61		abort();						\
62	}								\
63} while (0)
64#endif
65
66#ifndef assert_not_implemented
67#define	assert_not_implemented(e) do {					\
68	if (config_debug && !(e))					\
69		not_implemented();					\
70} while (0)
71#endif
72
73/* Use to assert a particular configuration, e.g., cassert(config_debug). */
74#define	cassert(c) do {							\
75	if ((c) == false)						\
76		not_reached();						\
77} while (0)
78
79#endif /* JEMALLOC_H_TYPES */
80/******************************************************************************/
81#ifdef JEMALLOC_H_STRUCTS
82
83#endif /* JEMALLOC_H_STRUCTS */
84/******************************************************************************/
85#ifdef JEMALLOC_H_EXTERNS
86
87int	buferror(int err, char *buf, size_t buflen);
88uintmax_t	malloc_strtoumax(const char *restrict nptr,
89    char **restrict endptr, int base);
90void	malloc_write(const char *s);
91
92/*
93 * malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating
94 * point math.
95 */
96int	malloc_vsnprintf(char *str, size_t size, const char *format,
97    va_list ap);
98int	malloc_snprintf(char *str, size_t size, const char *format, ...)
99    JEMALLOC_ATTR(format(printf, 3, 4));
100void	malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque,
101    const char *format, va_list ap);
102void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
103    const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
104void	malloc_printf(const char *format, ...)
105    JEMALLOC_ATTR(format(printf, 1, 2));
106
107#endif /* JEMALLOC_H_EXTERNS */
108/******************************************************************************/
109#ifdef JEMALLOC_H_INLINES
110
111#ifndef JEMALLOC_ENABLE_INLINE
112size_t	pow2_ceil(size_t x);
113size_t	lg_floor(size_t x);
114void	set_errno(int errnum);
115int	get_errno(void);
116#endif
117
118#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_))
119/* Compute the smallest power of 2 that is >= x. */
120JEMALLOC_INLINE size_t
121pow2_ceil(size_t x)
122{
123
124	x--;
125	x |= x >> 1;
126	x |= x >> 2;
127	x |= x >> 4;
128	x |= x >> 8;
129	x |= x >> 16;
130#if (LG_SIZEOF_PTR == 3)
131	x |= x >> 32;
132#endif
133	x++;
134	return (x);
135}
136
137#if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
138JEMALLOC_INLINE size_t
139lg_floor(size_t x)
140{
141	size_t ret;
142
143	asm ("bsr %1, %0"
144	    : "=r"(ret) // Outputs.
145	    : "r"(x)    // Inputs.
146	    );
147	return (ret);
148}
149#elif (defined(JEMALLOC_HAVE_BUILTIN_CLZ))
150JEMALLOC_INLINE size_t
151lg_floor(size_t x)
152{
153
154#if (LG_SIZEOF_PTR == LG_SIZEOF_INT)
155	return ((8 << LG_SIZEOF_PTR - 1) - __builtin_clz(x));
156#elif (LG_SIZEOF_PTR == LG_SIZEOF_LONG)
157	return ((8 << LG_SIZEOF_PTR - 1) - __builtin_clzl(x));
158#else
159#  error "Unsupported type sizes for lg_floor()"
160#endif
161}
162#else
163JEMALLOC_INLINE size_t
164lg_floor(size_t x)
165{
166
167        x |= (x >> 1);
168        x |= (x >> 2);
169        x |= (x >> 4);
170        x |= (x >> 8);
171        x |= (x >> 16);
172#if (LG_SIZEOF_PTR == 3 && LG_SIZEOF_PTR == LG_SIZEOF_LONG)
173        x |= (x >> 32);
174        return (65 - ffsl(~x));
175#elif (LG_SIZEOF_PTR == 2)
176        return (33 - ffs(~x));
177#else
178#  error "Unsupported type sizes for lg_floor()"
179#endif
180}
181#endif
182
183/* Sets error code */
184JEMALLOC_INLINE void
185set_errno(int errnum)
186{
187
188#ifdef _WIN32
189	SetLastError(errnum);
190#else
191	errno = errnum;
192#endif
193}
194
195/* Get last error code */
196JEMALLOC_INLINE int
197get_errno(void)
198{
199
200#ifdef _WIN32
201	return (GetLastError());
202#else
203	return (errno);
204#endif
205}
206#endif
207
208#endif /* JEMALLOC_H_INLINES */
209/******************************************************************************/
210