]> code.delx.au - pulseaudio/blob - src/pulsecore/macro.h
remap: Change remapping function argument type from void to int16_t / float as approp...
[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 #ifdef __GNUC__
181 #define PA_PRETTY_FUNCTION __PRETTY_FUNCTION__
182 #else
183 #define PA_PRETTY_FUNCTION ""
184 #endif
185
186 #define pa_return_if_fail(expr) \
187 do { \
188 if (PA_UNLIKELY(!(expr))) { \
189 pa_log_debug("Assertion '%s' failed at %s:%u, function %s.\n", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
190 return; \
191 } \
192 } while(false)
193
194 #define pa_return_val_if_fail(expr, val) \
195 do { \
196 if (PA_UNLIKELY(!(expr))) { \
197 pa_log_debug("Assertion '%s' failed at %s:%u, function %s.\n", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
198 return (val); \
199 } \
200 } while(false)
201
202 #define pa_return_null_if_fail(expr) pa_return_val_if_fail(expr, NULL)
203
204 /* pa_assert_se() is an assert which guarantees side effects of x,
205 * i.e. is never optimized away, regardless of NDEBUG or FASTPATH. */
206 #define pa_assert_se(expr) \
207 do { \
208 if (PA_UNLIKELY(!(expr))) { \
209 pa_log_error("Assertion '%s' failed at %s:%u, function %s(). Aborting.", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
210 abort(); \
211 } \
212 } while (false)
213
214 /* Does exactly nothing */
215 #define pa_nop() do {} while (false)
216
217 /* pa_assert() is an assert that may be optimized away by defining
218 * NDEBUG. pa_assert_fp() is an assert that may be optimized away by
219 * defining FASTPATH. It is supposed to be used in inner loops. It's
220 * there for extra paranoia checking and should probably be removed in
221 * production builds. */
222 #ifdef NDEBUG
223 #define pa_assert(expr) pa_nop()
224 #define pa_assert_fp(expr) pa_nop()
225 #elif defined (FASTPATH)
226 #define pa_assert(expr) pa_assert_se(expr)
227 #define pa_assert_fp(expr) pa_nop()
228 #else
229 #define pa_assert(expr) pa_assert_se(expr)
230 #define pa_assert_fp(expr) pa_assert_se(expr)
231 #endif
232
233 #ifdef NDEBUG
234 #define pa_assert_not_reached() pa_nop()
235 #else
236 #define pa_assert_not_reached() \
237 do { \
238 pa_log_error("Code should not be reached at %s:%u, function %s(). Aborting.", __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
239 abort(); \
240 } while (false)
241 #endif
242
243 /* A compile time assertion */
244 #define pa_assert_cc(expr) \
245 do { \
246 switch (0) { \
247 case 0: \
248 case !!(expr): \
249 ; \
250 } \
251 } while (false)
252
253 #define PA_PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
254 #define PA_UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))
255
256 #define PA_PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
257 #define PA_UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u)))
258
259 #define PA_PTR_TO_INT(p) ((int) ((intptr_t) (p)))
260 #define PA_INT_TO_PTR(u) ((void*) ((intptr_t) (u)))
261
262 #define PA_PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
263 #define PA_INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))
264
265 #ifdef OS_IS_WIN32
266 #define PA_PATH_SEP "\\"
267 #define PA_PATH_SEP_CHAR '\\'
268 #else
269 #define PA_PATH_SEP "/"
270 #define PA_PATH_SEP_CHAR '/'
271 #endif
272
273 #if defined(__GNUC__) && defined(__ELF__)
274
275 #define PA_WARN_REFERENCE(sym, msg) \
276 __asm__(".section .gnu.warning." #sym); \
277 __asm__(".asciz \"" msg "\""); \
278 __asm__(".previous")
279
280 #else
281
282 #define PA_WARN_REFERENCE(sym, msg)
283
284 #endif
285
286 #if defined(__i386__) || defined(__x86_64__)
287 #define PA_DEBUG_TRAP __asm__("int $3")
288 #else
289 #define PA_DEBUG_TRAP raise(SIGTRAP)
290 #endif
291
292 #define pa_memzero(x,l) (memset((x), 0, (l)))
293 #define pa_zero(x) (pa_memzero(&(x), sizeof(x)))
294
295 #define PA_INT_TYPE_SIGNED(type) (!!((type) 0 > (type) -1))
296
297 #define PA_INT_TYPE_MAX(type) \
298 ((type) (PA_INT_TYPE_SIGNED(type) \
299 ? ~(~(type) 0 << (8*sizeof(type)-1)) \
300 : (type) -1))
301
302 #define PA_INT_TYPE_MIN(type) \
303 ((type) (PA_INT_TYPE_SIGNED(type) \
304 ? (~(type) 0 << (8*sizeof(type)-1)) \
305 : (type) 0))
306
307 /* We include this at the very last place */
308 #include <pulsecore/log.h>
309
310 #endif