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