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