kernel_defines.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Freie Universit├Ąt Berlin
3  * 2017 HAW-Hamburg
4  *
5  * This file is subject to the terms and conditions of the GNU Lesser
6  * General Public License v2.1. See the file LICENSE in the top level
7  * directory for more details.
8  */
9 
21 #ifndef KERNEL_DEFINES_H
22 #define KERNEL_DEFINES_H
23 
24 #include <stddef.h>
25 #include <stdint.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /* uncrustify gets mightily confused by these macros... */
32 /* begin{code-style-ignore} */
33 
47 #if __STDC_VERSION__ >= 201112L
48 # define container_of(PTR, TYPE, MEMBER) \
49  (_Generic((PTR), \
50  const __typeof__ (((TYPE *) 0)->MEMBER) *: \
51  ((TYPE *) ((uintptr_t) (PTR) - offsetof(TYPE, MEMBER))), \
52  __typeof__ (((TYPE *) 0)->MEMBER) *: \
53  ((TYPE *) ((uintptr_t) (PTR) - offsetof(TYPE, MEMBER))) \
54  ))
55 #elif defined __GNUC__
56 # define container_of(PTR, TYPE, MEMBER) \
57  (__extension__ ({ \
58  __extension__ const __typeof__ (((TYPE *) 0)->MEMBER) *__m____ = (PTR); \
59  ((TYPE *) ((uintptr_t) __m____ - offsetof(TYPE, MEMBER))); \
60  }))
61 #else
62 # define container_of(PTR, TYPE, MEMBER) \
63  ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER)))
64 #endif
65 
74 #define index_of(ARRAY, ELEMENT) (((uintptr_t)(ELEMENT) - (uintptr_t)(ARRAY)) / sizeof((ARRAY)[0]))
75 
81 #ifdef __GNUC__
82 #define NORETURN __attribute__((noreturn))
83 #else
84 #define NORETURN
85 #endif
86 
93 #ifdef __GNUC__
94 #define CONST __attribute__((const))
95 #else
96 #define CONST
97 #endif
98 
106 #ifdef __GNUC__
107 #define PURE __attribute__((pure))
108 #else
109 #define PURE
110 #endif
111 
119 #if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ >= 5)
120 #define UNREACHABLE() __builtin_unreachable()
121 #else
122 #define UNREACHABLE() do { /* nothing */ } while (1)
123 #endif
124 
131 #ifndef ARRAY_SIZE
132 #define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
133 #endif
134 
167 #define IS_ACTIVE(macro) __is_active(macro)
168 
178 #define IS_USED(module) IS_ACTIVE(module)
179 
205 #define RIOT_VERSION_NUM(major, minor, patch, extra) \
206  (((0ULL + major) << 48) + ((0ULL + minor) << 32) + \
207  ((0ULL + patch) << 16) + (extra))
208 
220 #define WITHOUT_PEDANTIC(...) \
221  _Pragma("GCC diagnostic push") \
222  _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
223  __VA_ARGS__ \
224  _Pragma("GCC diagnostic pop")
225 
236 #define DECLARE_CONSTANT(identifier, const_expr) \
237  WITHOUT_PEDANTIC(enum { identifier = const_expr };)
238 
239 #if DOXYGEN
252 #define IS_CT_CONSTANT(expr) <IMPLEMENTATION>
253 #elif defined(__GNUC__)
254 /* both clang and gcc (which both define __GNUC__) support this */
255 #define IS_CT_CONSTANT(expr) __builtin_constant_p(expr)
256 #else
257 #define IS_CT_CONSTANT(expr) 0
258 #endif
259 
263 /* Here a prefix "__PREFIX_WHEN_" is added to the macro. So if it was a 1 we
264  * have "__PREFIX_WHEN_1", and if it was not defined we have "__PREFIX_WHEN_".
265  */
266 #define __is_active(val) ___is_active(__PREFIX_WHEN_##val)
267 
268 /* With this placeholder we turn the original value into two arguments when the
269  * original value was defined as 1 (note the comma).
270  */
271 #define __PREFIX_WHEN_1 0,
272 
273 /* Here we add two extra arguments, that way the next macro can accept varargs.
274  *
275  * If the original macro was defined as 1, this will have three arguments
276  * (__take_second_arg(0, 1, 0, 0)), otherwise it will have two
277  * (__take_second_arg(__PREFIX_WHEN_ 1, 0, 0)). The third zero is there just to
278  * be compliant with C99, which states that when a function-like macro ends
279  * with ellipsis (...) it should be called with at least one argument for the
280  * variable list.
281  */
282 #define ___is_active(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0, 0)
283 
284 /* Finally, we just always take the second argument, which will be either 1
285  * (when three arguments are passed, i.e. macro was defined as 1) or 0 (when
286  * only two arguments are passed).
287  */
288 #define __take_second_arg(__ignored, val, ...) val
293 /* end{code-style-ignore} */
294 
295 #ifdef __cplusplus
296 }
297 #endif
298 
299 #endif /* KERNEL_DEFINES_H */