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