]> code.delx.au - pulseaudio/blob - src/pulsecore/macro.h
Remove pa_bool_t and replace it with bool.
[pulseaudio] / src / pulsecore / macro.h
1 #ifndef foopulsemacrohfoo
2 #define foopulsemacrohfoo
3
4 /***
5 This file is part of PulseAudio.
6
7 Copyright 2004-2006 Lennart Poettering
8
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License,
12 or (at your option) any later version.
13
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 USA.
23 ***/
24
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <assert.h>
28 #include <limits.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdbool.h>
34
35 #ifndef PACKAGE
36 #error "Please include config.h before including this file!"
37 #endif
38
39 #ifndef PA_LIKELY
40 #ifdef __GNUC__
41 #define PA_LIKELY(x) (__builtin_expect(!!(x),1))
42 #define PA_UNLIKELY(x) (__builtin_expect(!!(x),0))
43 #else
44 #define PA_LIKELY(x) (x)
45 #define PA_UNLIKELY(x) (x)
46 #endif
47 #endif
48
49 #if defined(PAGE_SIZE)
50 #define PA_PAGE_SIZE ((size_t) PAGE_SIZE)
51 #elif defined(PAGESIZE)
52 #define PA_PAGE_SIZE ((size_t) PAGESIZE)
53 #elif defined(HAVE_SYSCONF)
54 #define PA_PAGE_SIZE ((size_t) (sysconf(_SC_PAGE_SIZE)))
55 #else
56 /* Let's hope it's like x86. */
57 #define PA_PAGE_SIZE ((size_t) 4096)
58 #endif
59
60 /* Rounds down */
61 static inline void* PA_ALIGN_PTR(const void *p) {
62 return (void*) (((size_t) p) & ~(sizeof(void*) - 1));
63 }
64
65 /* Rounds up */
66 static inline size_t PA_ALIGN(size_t l) {
67 return ((l + sizeof(void*) - 1) & ~(sizeof(void*) - 1));
68 }
69
70 /* Rounds down */
71 static inline void* PA_PAGE_ALIGN_PTR(const void *p) {
72 return (void*) (((size_t) p) & ~(PA_PAGE_SIZE - 1));
73 }
74
75 /* Rounds up */
76 static inline size_t PA_PAGE_ALIGN(size_t l) {
77 return (l + PA_PAGE_SIZE - 1) & ~(PA_PAGE_SIZE - 1);
78 }
79
80 #define PA_ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
81
82 #if defined(__GNUC__)
83 #define PA_DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n)))
84 #else
85 #define PA_DECLARE_ALIGNED(n,t,v) t v
86 #endif
87
88 #ifdef __GNUC__
89 #define typeof __typeof__
90 #endif
91
92 /* The users of PA_MIN and PA_MAX, PA_CLAMP, PA_ROUND_UP should be
93 * aware that these macros on non-GCC executed code with side effects
94 * twice. It is thus considered misuse to use code with side effects
95 * as arguments to MIN and MAX. */
96
97 #ifdef __GNUC__
98 #define PA_MAX(a,b) \
99 __extension__ ({ \
100 typeof(a) _a = (a); \
101 typeof(b) _b = (b); \
102 _a > _b ? _a : _b; \
103 })
104 #else
105 #define PA_MAX(a, b) ((a) > (b) ? (a) : (b))
106 #endif
107
108 #ifdef __GNUC__
109 #define PA_MIN(a,b) \
110 __extension__ ({ \
111 typeof(a) _a = (a); \
112 typeof(b) _b = (b); \
113 _a < _b ? _a : _b; \
114 })
115 #else
116 #define PA_MIN(a, b) ((a) < (b) ? (a) : (b))
117 #endif
118
119 #ifdef __GNUC__
120 #define PA_CLAMP(x, low, high) \
121 __extension__ ({ \
122 typeof(x) _x = (x); \
123 typeof(low) _low = (low); \
124 typeof(high) _high = (high); \
125 ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
126 })
127 #else
128 #define PA_CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
129 #endif
130
131 #ifdef __GNUC__
132 #define PA_CLAMP_UNLIKELY(x, low, high) \
133 __extension__ ({ \
134 typeof(x) _x = (x); \
135 typeof(low) _low = (low); \
136 typeof(high) _high = (high); \
137 (PA_UNLIKELY(_x > _high) ? _high : (PA_UNLIKELY(_x < _low) ? _low : _x)); \
138 })
139 #else
140 #define PA_CLAMP_UNLIKELY(x, low, high) (PA_UNLIKELY((x) > (high)) ? (high) : (PA_UNLIKELY((x) < (low)) ? (low) : (x)))
141 #endif
142
143 /* We don't define a PA_CLAMP_LIKELY here, because it doesn't really
144 * make sense: we cannot know if it is more likely that the values is
145 * lower or greater than the boundaries.*/
146
147 #ifdef __GNUC__
148 #define PA_ROUND_UP(a, b) \
149 __extension__ ({ \
150 typeof(a) _a = (a); \
151 typeof(b) _b = (b); \
152 ((_a + _b - 1) / _b) * _b; \
153 })
154 #else
155 #define PA_ROUND_UP(a, b) ((((a) + (b) - 1) / (b)) * (b))
156 #endif
157
158 #ifdef __GNUC__
159 #define PA_ROUND_DOWN(a, b) \
160 __extension__ ({ \
161 typeof(a) _a = (a); \
162 typeof(b) _b = (b); \
163 (_a / _b) * _b; \
164 })
165 #else
166 #define PA_ROUND_DOWN(a, b) (((a) / (b)) * (b))
167 #endif
168
169 #ifdef __GNUC__
170 #define PA_CLIP_SUB(a, b) \
171 __extension__ ({ \
172 typeof(a) _a = (a); \
173 typeof(b) _b = (b); \
174 _a > _b ? _a - _b : 0; \
175 })
176 #else
177 #define PA_CLIP_SUB(a, b) ((a) > (b) ? (a) - (b) : 0)
178 #endif
179
180 /* This type is not intended to be used in exported APIs! Use classic "int" there! */
181 #ifdef HAVE_STD_BOOL
182 typedef bool pa_bool_t;
183 #else
184 typedef int pa_bool_t;
185 #endif
186
187 #ifndef FALSE
188 #define FALSE ((pa_bool_t) 0)
189 #endif
190
191 #ifndef TRUE
192 #define TRUE (!FALSE)
193 #endif
194
195 #ifdef __GNUC__
196 #define PA_PRETTY_FUNCTION __PRETTY_FUNCTION__
197 #else
198 #define PA_PRETTY_FUNCTION ""
199 #endif
200
201 #define pa_return_if_fail(expr) \
202 do { \
203 if (PA_UNLIKELY(!(expr))) { \
204 pa_log_debug("Assertion '%s' failed at %s:%u, function %s.\n", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
205 return; \
206 } \
207 } while(false)
208
209 #define pa_return_val_if_fail(expr, val) \
210 do { \
211 if (PA_UNLIKELY(!(expr))) { \
212 pa_log_debug("Assertion '%s' failed at %s:%u, function %s.\n", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
213 return (val); \
214 } \
215 } while(false)
216
217 #define pa_return_null_if_fail(expr) pa_return_val_if_fail(expr, NULL)
218
219 /* pa_assert_se() is an assert which guarantees side effects of x,
220 * i.e. is never optimized away, regardless of NDEBUG or FASTPATH. */
221 #define pa_assert_se(expr) \
222 do { \
223 if (PA_UNLIKELY(!(expr))) { \
224 pa_log_error("Assertion '%s' failed at %s:%u, function %s(). Aborting.", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
225 abort(); \
226 } \
227 } while (false)
228
229 /* Does exactly nothing */
230 #define pa_nop() do {} while (false)
231
232 /* pa_assert() is an assert that may be optimized away by defining
233 * NDEBUG. pa_assert_fp() is an assert that may be optimized away by
234 * defining FASTPATH. It is supposed to be used in inner loops. It's
235 * there for extra paranoia checking and should probably be removed in
236 * production builds. */
237 #ifdef NDEBUG
238 #define pa_assert(expr) pa_nop()
239 #define pa_assert_fp(expr) pa_nop()
240 #elif defined (FASTPATH)
241 #define pa_assert(expr) pa_assert_se(expr)
242 #define pa_assert_fp(expr) pa_nop()
243 #else
244 #define pa_assert(expr) pa_assert_se(expr)
245 #define pa_assert_fp(expr) pa_assert_se(expr)
246 #endif
247
248 #ifdef NDEBUG
249 #define pa_assert_not_reached() pa_nop()
250 #else
251 #define pa_assert_not_reached() \
252 do { \
253 pa_log_error("Code should not be reached at %s:%u, function %s(). Aborting.", __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
254 abort(); \
255 } while (false)
256 #endif
257
258 /* A compile time assertion */
259 #define pa_assert_cc(expr) \
260 do { \
261 switch (0) { \
262 case 0: \
263 case !!(expr): \
264 ; \
265 } \
266 } while (false)
267
268 #define PA_PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
269 #define PA_UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))
270
271 #define PA_PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
272 #define PA_UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u)))
273
274 #define PA_PTR_TO_INT(p) ((int) ((intptr_t) (p)))
275 #define PA_INT_TO_PTR(u) ((void*) ((intptr_t) (u)))
276
277 #define PA_PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
278 #define PA_INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))
279
280 #ifdef OS_IS_WIN32
281 #define PA_PATH_SEP "\\"
282 #define PA_PATH_SEP_CHAR '\\'
283 #else
284 #define PA_PATH_SEP "/"
285 #define PA_PATH_SEP_CHAR '/'
286 #endif
287
288 #if defined(__GNUC__) && defined(__ELF__)
289
290 #define PA_WARN_REFERENCE(sym, msg) \
291 __asm__(".section .gnu.warning." #sym); \
292 __asm__(".asciz \"" msg "\""); \
293 __asm__(".previous")
294
295 #else
296
297 #define PA_WARN_REFERENCE(sym, msg)
298
299 #endif
300
301 #if defined(__i386__) || defined(__x86_64__)
302 #define PA_DEBUG_TRAP __asm__("int $3")
303 #else
304 #define PA_DEBUG_TRAP raise(SIGTRAP)
305 #endif
306
307 #define pa_memzero(x,l) (memset((x), 0, (l)))
308 #define pa_zero(x) (pa_memzero(&(x), sizeof(x)))
309
310 #define PA_INT_TYPE_SIGNED(type) (!!((type) 0 > (type) -1))
311
312 #define PA_INT_TYPE_MAX(type) \
313 ((type) (PA_INT_TYPE_SIGNED(type) \
314 ? ~(~(type) 0 << (8*sizeof(type)-1)) \
315 : (type) -1))
316
317 #define PA_INT_TYPE_MIN(type) \
318 ((type) (PA_INT_TYPE_SIGNED(type) \
319 ? (~(type) 0 << (8*sizeof(type)-1)) \
320 : (type) 0))
321
322 /* We include this at the very last place */
323 #include <pulsecore/log.h>
324
325 #endif