]> code.delx.au - pulseaudio/blob - src/pulsecore/macro.h
remap: make the MMX code pretier
[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
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 /* The users of PA_MIN and PA_MAX, PA_CLAMP, PA_ROUND_UP should be
84 * aware that these macros on non-GCC executed code with side effects
85 * twice. It is thus considered misuse to use code with side effects
86 * as arguments to MIN and MAX. */
87
88 #ifdef __GNUC__
89 #define PA_MAX(a,b) \
90 __extension__ ({ \
91 typeof(a) _a = (a); \
92 typeof(b) _b = (b); \
93 _a > _b ? _a : _b; \
94 })
95 #else
96 #define PA_MAX(a, b) ((a) > (b) ? (a) : (b))
97 #endif
98
99 #ifdef __GNUC__
100 #define PA_MIN(a,b) \
101 __extension__ ({ \
102 typeof(a) _a = (a); \
103 typeof(b) _b = (b); \
104 _a < _b ? _a : _b; \
105 })
106 #else
107 #define PA_MIN(a, b) ((a) < (b) ? (a) : (b))
108 #endif
109
110 #ifdef __GNUC__
111 #define PA_CLAMP(x, low, high) \
112 __extension__ ({ \
113 typeof(x) _x = (x); \
114 typeof(low) _low = (low); \
115 typeof(high) _high = (high); \
116 ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
117 })
118 #else
119 #define PA_CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
120 #endif
121
122 #ifdef __GNUC__
123 #define PA_CLAMP_UNLIKELY(x, low, high) \
124 __extension__ ({ \
125 typeof(x) _x = (x); \
126 typeof(low) _low = (low); \
127 typeof(high) _high = (high); \
128 (PA_UNLIKELY(_x > _high) ? _high : (PA_UNLIKELY(_x < _low) ? _low : _x)); \
129 })
130 #else
131 #define PA_CLAMP_UNLIKELY(x, low, high) (PA_UNLIKELY((x) > (high)) ? (high) : (PA_UNLIKELY((x) < (low)) ? (low) : (x)))
132 #endif
133
134 /* We don't define a PA_CLAMP_LIKELY here, because it doesn't really
135 * make sense: we cannot know if it is more likely that the values is
136 * lower or greater than the boundaries.*/
137
138 #ifdef __GNUC__
139 #define PA_ROUND_UP(a, b) \
140 __extension__ ({ \
141 typeof(a) _a = (a); \
142 typeof(b) _b = (b); \
143 ((_a + _b - 1) / _b) * _b; \
144 })
145 #else
146 #define PA_ROUND_UP(a, b) ((((a) + (b) - 1) / (b)) * (b))
147 #endif
148
149 #ifdef __GNUC__
150 #define PA_ROUND_DOWN(a, b) \
151 __extension__ ({ \
152 typeof(a) _a = (a); \
153 typeof(b) _b = (b); \
154 (_a / _b) * _b; \
155 })
156 #else
157 #define PA_ROUND_DOWN(a, b) (((a) / (b)) * (b))
158 #endif
159
160 /* This type is not intended to be used in exported APIs! Use classic "int" there! */
161 #ifdef HAVE_STD_BOOL
162 typedef _Bool pa_bool_t;
163 #else
164 typedef int pa_bool_t;
165 #endif
166
167 #ifndef FALSE
168 #define FALSE ((pa_bool_t) 0)
169 #endif
170
171 #ifndef TRUE
172 #define TRUE (!FALSE)
173 #endif
174
175 #ifdef __GNUC__
176 #define PA_PRETTY_FUNCTION __PRETTY_FUNCTION__
177 #else
178 #define PA_PRETTY_FUNCTION ""
179 #endif
180
181 #define pa_return_if_fail(expr) \
182 do { \
183 if (PA_UNLIKELY(!(expr))) { \
184 pa_log_debug("Assertion '%s' failed at %s:%u, function %s.\n", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
185 return; \
186 } \
187 } while(FALSE)
188
189 #define pa_return_val_if_fail(expr, val) \
190 do { \
191 if (PA_UNLIKELY(!(expr))) { \
192 pa_log_debug("Assertion '%s' failed at %s:%u, function %s.\n", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
193 return (val); \
194 } \
195 } while(FALSE)
196
197 #define pa_return_null_if_fail(expr) pa_return_val_if_fail(expr, NULL)
198
199 /* pa_assert_se() is an assert which guarantees side effects of x,
200 * i.e. is never optimized away, regardless of NDEBUG or FASTPATH. */
201 #define pa_assert_se(expr) \
202 do { \
203 if (PA_UNLIKELY(!(expr))) { \
204 pa_log_error("Assertion '%s' failed at %s:%u, function %s(). Aborting.", #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
205 abort(); \
206 } \
207 } while (FALSE)
208
209 /* Does exactly nothing */
210 #define pa_nop() do {} while (FALSE)
211
212 /* pa_assert() is an assert that may be optimized away by defining
213 * NDEBUG. pa_assert_fp() is an assert that may be optimized away by
214 * defining FASTPATH. It is supposed to be used in inner loops. It's
215 * there for extra paranoia checking and should probably be removed in
216 * production builds. */
217 #ifdef NDEBUG
218 #define pa_assert(expr) pa_nop()
219 #define pa_assert_fp(expr) pa_nop()
220 #elif defined (FASTPATH)
221 #define pa_assert(expr) pa_assert_se(expr)
222 #define pa_assert_fp(expr) pa_nop()
223 #else
224 #define pa_assert(expr) pa_assert_se(expr)
225 #define pa_assert_fp(expr) pa_assert_se(expr)
226 #endif
227
228 #ifdef NDEBUG
229 #define pa_assert_not_reached() pa_nop()
230 #else
231 #define pa_assert_not_reached() \
232 do { \
233 pa_log_error("Code should not be reached at %s:%u, function %s(). Aborting.", __FILE__, __LINE__, PA_PRETTY_FUNCTION); \
234 abort(); \
235 } while (FALSE)
236 #endif
237
238 /* A compile time assertion */
239 #define pa_assert_cc(expr) \
240 do { \
241 switch (0) { \
242 case 0: \
243 case !!(expr): \
244 ; \
245 } \
246 } while (FALSE)
247
248 #define PA_PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
249 #define PA_UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))
250
251 #define PA_PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
252 #define PA_UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u)))
253
254 #define PA_PTR_TO_INT(p) ((int) ((intptr_t) (p)))
255 #define PA_INT_TO_PTR(u) ((void*) ((intptr_t) (u)))
256
257 #define PA_PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
258 #define PA_INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))
259
260 #ifdef OS_IS_WIN32
261 #define PA_PATH_SEP "\\"
262 #define PA_PATH_SEP_CHAR '\\'
263 #else
264 #define PA_PATH_SEP "/"
265 #define PA_PATH_SEP_CHAR '/'
266 #endif
267
268 #if defined(__GNUC__) && defined(__ELF__)
269
270 #define PA_WARN_REFERENCE(sym, msg) \
271 __asm__(".section .gnu.warning." #sym); \
272 __asm__(".asciz \"" msg "\""); \
273 __asm__(".previous")
274
275 #else
276
277 #define PA_WARN_REFERENCE(sym, msg)
278
279 #endif
280
281 #if defined(__i386__) || defined(__x86_64__)
282 #define PA_DEBUG_TRAP __asm__("int $3")
283 #else
284 #define PA_DEBUG_TRAP raise(SIGTRAP)
285 #endif
286
287 #define pa_memzero(x,l) (memset((x), 0, (l)))
288 #define pa_zero(x) (pa_memzero(&(x), sizeof(x)))
289
290 /* We include this at the very last place */
291 #include <pulsecore/log.h>
292
293 #endif