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 
26 #ifdef __cplusplus
27  extern "C" {
28 #endif
29 
43 #if __STDC_VERSION__ >= 201112L
44 # define container_of(PTR, TYPE, MEMBER) \
45  (_Generic((PTR), \
46  const __typeof__ (((TYPE *) 0)->MEMBER) *: \
47  ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))), \
48  __typeof__ (((TYPE *) 0)->MEMBER) *: \
49  ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))) \
50  ))
51 #elif defined __GNUC__
52 # define container_of(PTR, TYPE, MEMBER) \
53  (__extension__ ({ \
54  __extension__ const __typeof__ (((TYPE *) 0)->MEMBER) *__m____ = (PTR); \
55  ((TYPE *) ((char *) __m____ - offsetof(TYPE, MEMBER))); \
56  }))
57 #else
58 # define container_of(PTR, TYPE, MEMBER) \
59  ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER)))
60 #endif
61 
67 #ifdef __GNUC__
68 #define NORETURN __attribute__((noreturn))
69 #else
70 #define NORETURN
71 #endif
72 
79 #ifdef __GNUC__
80 #define CONST __attribute__((const))
81 #else
82 #define CONST
83 #endif
84 
92 #ifdef __GNUC__
93 #define PURE __attribute__((pure))
94 #else
95 #define PURE
96 #endif
97 
105 #if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ >= 5)
106 #define UNREACHABLE() __builtin_unreachable()
107 #else
108 #define UNREACHABLE() do { /* nothing */ } while (1)
109 #endif
110 
117 #ifndef ARRAY_SIZE
118 #define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
119 #endif
120 
127 #define ALIGN_OF(T) (offsetof(struct { char c; T t; }, t))
128 
139 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
140 
173 #define IS_ACTIVE(macro) __is_active(macro)
174 
184 #define IS_USED(module) IS_ACTIVE(module)
185 
189 /* Here a prefix "__PREFIX_WHEN_" is added to the macro. So if it was a 1 we
190  * have "__PREFIX_WHEN_1", and if it was not defined we have "__PREFIX_WHEN_".
191  */
192 #define __is_active(val) ___is_active(__PREFIX_WHEN_##val)
193 
194 /* With this placeholder we turn the original value into two arguments when the
195  * original value was defined as 1 (note the comma).
196  */
197 #define __PREFIX_WHEN_1 0,
198 
199 /* Here we add two extra arguments, that way the next macro can accept varargs.
200  *
201  * If the original macro was defined as 1, this will have three arguments
202  * (__take_second_arg(0, 1, 0, 0)), otherwise it will have two
203  * (__take_second_arg(__PREFIX_WHEN_ 1, 0, 0)). The third zero is there just to
204  * be compliant with C99, which states that when a function-like macro ends
205  * with ellipsis (...) it should be called with at least one argument for the
206  * variable list.
207  */
208 #define ___is_active(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0, 0)
209 
210 /* Finally, we just always take the second argument, which will be either 1
211  * (when three arguments are passed, i.e. macro was defined as 1) or 0 (when
212  * only two arguments are passed).
213  */
214 #define __take_second_arg(__ignored, val, ...) val
215 
219 #ifdef __cplusplus
220 }
221 #endif
222 
223 #endif /* KERNEL_DEFINES_H */
224