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