1 /*****************************************************************************/
2 /**
3  * \file
4  * L4 compiler related defines.
5  * \ingroup l4_api
6  */
7 /*
8  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
10  *               Frank Mehnert <fm3@os.inf.tu-dresden.de>,
11  *               Jork Löser <jork@os.inf.tu-dresden.de>,
12  *               Ronald Aigner <ra3@os.inf.tu-dresden.de>
13  *     economic rights: Technische Universität Dresden (Germany)
14  *
15  * This file is part of TUD:OS and distributed under the terms of the
16  * GNU General Public License 2.
17  * Please see the COPYING-GPL-2 file for details.
18  *
19  * As a special exception, you may use this file as part of a free software
20  * library without restriction.  Specifically, if other files instantiate
21  * templates or use macros or inline functions from this file, or you compile
22  * this file and link it with other files to produce an executable, this
23  * file does not by itself cause the resulting executable to be covered by
24  * the GNU General Public License.  This exception does not however
25  * invalidate any other reasons why the executable file might be covered by
26  * the GNU General Public License.
27  */
28 /*****************************************************************************/
29 #ifndef __L4_COMPILER_H__
30 #define __L4_COMPILER_H__
31 
32 #if !defined(__ASSEMBLY__) && !defined(__ASSEMBLER__)
33 
34 /**
35  * \addtogroup l4sys_defines
36  *
37  * \includefile{l4/sys/compiler.h}
38  */
39 /*@{*/
40 
41 /**
42  * L4 Inline function attribute.
43  * \hideinitializer
44  */
45 #ifndef L4_INLINE
46 #ifndef __cplusplus
47 #  ifdef __OPTIMIZE__
48 #    define L4_INLINE_STATIC static __inline__
49 #    define L4_INLINE_EXTERN extern __inline__
50 #    ifdef __GNUC_STDC_INLINE__
51 #      define L4_INLINE L4_INLINE_STATIC
52 #    else
53 #      define L4_INLINE L4_INLINE_EXTERN
54 #    endif
55 #  else /* ! __OPTIMIZE__ */
56 #    define L4_INLINE static
57 #  endif /* ! __OPTIMIZE__ */
58 #else /* __cplusplus */
59 #  define L4_INLINE inline
60 #endif  /* __cplusplus */
61 #endif  /* L4_INLINE */
62 
63 /**
64  * Always inline a function
65  * \hideinitializer
66  */
67 #define L4_ALWAYS_INLINE L4_INLINE __attribute__((__always_inline__))
68 
69 
70 #define L4_DECLARE_CONSTRUCTOR(func, prio) \
71   static inline __attribute__((constructor(prio))) void func ## _ctor_func(void) { func(); }
72 
73 
74 /**
75  * Start section with C types and functions.
76  * \def     __BEGIN_DECLS
77  * \hideinitializer
78  */
79 /**
80  * End section with C types and functions.
81  * \def     __END_DECLS
82  * \hideinitializer
83  */
84 /**
85  * Start section with C types and functions.
86  * \def     EXTERN_C_BEGIN
87  * \hideinitializer
88  */
89 /**
90  * End section with C types and functions.
91  * \def     EXTERN_C_END
92  * \hideinitializer
93  */
94 /**
95  * Mark C types and functions.
96  * \def     EXTERN_C
97  * \hideinitializer
98  */
99 
100 /**
101  * \def L4_NOTHROW
102  * \hideinitializer
103  * Mark a function declaration and definition as never throwing an exception.
104  * (Also for C code).
105  *
106  * This macro shall be used to mark C and C++ functions that never
107  * throw any exception.  Note that also C functions may throw exceptions
108  * according to the compilers ABI and shall be marked with L4_NOTHROW
109  * if they never do.  In C++ this is equivalent to \c throw().
110  *
111  * \code
112  * int foo() L4_NOTHROW;
113  * ...
114  * int foo() L4_NOTHROW
115  * {
116  *   ...
117  *   return result;
118  * }
119  * \endcode
120  *
121  */
122 
123 /**
124  * \def L4_EXPORT
125  * \hideinitializer
126  * Attribute to mark functions, variables, and data types as being exported
127  * from a library.
128  *
129  * All data types, functions, and global variables that shall be exported
130  * from a library shall be marked with this attribute.  The default may become
131  * to hide everything that is not marked as L4_EXPORT from the users of a
132  * library and provide the possibility for aggressive optimization of all
133  * those internal functionality of a library.
134  *
135  * Usage:
136  * \code
137  * class L4_EXPORT My_class
138  * {
139  *   ...
140  * };
141  *
142  * int L4_EXPORT function(void);
143  *
144  * int L4_EXPORT global_data; // global data is not recommended
145  * \endcode
146  *
147  */
148 
149 /**
150  * \def L4_HIDDEN
151  * \hideinitializer
152  * Attribute to mark functions, variables, and data types as being explicitly
153  * hidden from users of a library.
154  *
155  * This attribute is intended for functions, data, and data types that
156  * shall never be visible outside of a library.  In particular, for shared
157  * libraries this may result in much faster code within the library and short
158  * linking times.
159  *
160  * \code
161  * class L4_HIDDEN My_class
162  * {
163  *   ...
164  * };
165  *
166  * int L4_HIDDEN function(void);
167  *
168  * int L4_HIDDEN global_data; // global data is not recommended
169  * \endcode
170  */
171 #ifndef __cplusplus
172 #  define L4_NOTHROW__A       __attribute__((nothrow))
173 #  define L4_NOTHROW
174 #  define EXTERN_C_BEGIN
175 #  define EXTERN_C_END
176 #  define EXTERN_C
177 #  ifndef __BEGIN_DECLS
178 #    define __BEGIN_DECLS
179 #  endif
180 #  ifndef __END_DECLS
181 #    define __END_DECLS
182 #  endif
183 #  define L4_DEFAULT_PARAM(x)
184 #else /* __cplusplus */
185 #  if __cplusplus >= 201103L
186 #    define L4_NOTHROW noexcept
187 #  else /* C++ < 11 */
188 #    define L4_NOTHROW throw()
189 #  endif
190 #  define EXTERN_C_BEGIN extern "C" {
191 #  define EXTERN_C_END }
192 #  define EXTERN_C extern "C"
193 #  ifndef __BEGIN_DECLS
194 #    define __BEGIN_DECLS extern "C" {
195 #  endif
196 #  ifndef __END_DECLS
197 #    define __END_DECLS }
198 #  endif
199 #  define L4_DEFAULT_PARAM(x) = x
200 #endif /* __cplusplus */
201 
202 /**
203  * Noreturn function attribute.
204  * \hideinitializer
205  */
206 #define L4_NORETURN __attribute__((noreturn))
207 
208 #define L4_PURE __attribute__((pure))
209 
210 /**
211  * No instrumentation function attribute.
212  * \hideinitializer
213  */
214 #define L4_NOINSTRUMENT __attribute__((no_instrument_function))
215 #ifndef L4_HIDDEN
216 #  define L4_HIDDEN __attribute__((visibility("hidden")))
217 #endif
218 #ifndef L4_EXPORT
219 #  define L4_EXPORT __attribute__((visibility("default")))
220 #endif
221 #ifndef L4_EXPORT_TYPE
222 #  ifdef __cplusplus
223 #    define L4_EXPORT_TYPE __attribute__((visibility("default")))
224 #  else
225 #    define L4_EXPORT_TYPE
226 #  endif
227 #endif
228 #define L4_STRONG_ALIAS(name, aliasname) L4__STRONG_ALIAS(name, aliasname)
229 #define L4__STRONG_ALIAS(name, aliasname) \
230   extern __typeof (name) aliasname __attribute__ ((alias (#name)));
231 
232 
233 #endif /* !__ASSEMBLY__ */
234 
235 #include <l4/sys/linkage.h>
236 
237 #define L4_LIKELY(x)	__builtin_expect((x),1)   ///< Expression is likely to execute. \hideinitializer
238 #define L4_UNLIKELY(x)	__builtin_expect((x),0)   ///< Expression is unlikely to execute. \hideinitializer
239 
240 /* Make sure that the function is not removed by optimization. Without the
241  * "used" attribute, unreferenced static functions are removed. */
242 #define L4_STICKY(x)     __attribute__((used)) x         ///< Mark symbol sticky (even not there) \hideinitializer
243 #define L4_DEPRECATED(s) __attribute__((deprecated(s)))  ///< Mark symbol deprecated. \hideinitializer
244 
245 #ifndef __GXX_EXPERIMENTAL_CXX0X__
246 #ifndef static_assert
247 #define static_assert(x, y) \
248   do { (void)sizeof(char[-(!(x))]); } while (0)
249 #endif
250 #endif
251 
252 #define L4_stringify_helper(x) #x                       ///< stringify helper. \hideinitializer
253 #define L4_stringify(x)        L4_stringify_helper(x)   ///< stringify. \hideinitializer
254 
255 #ifndef __ASSEMBLER__
256 /**
257  * Memory barrier.
258  */
259 L4_INLINE void l4_barrier(void);
260 
261 /**
262  * Memory barrier.
263  */
264 L4_INLINE void l4_mb(void);
265 
266 /**
267  * Write memory barrier.
268  */
269 L4_INLINE void l4_wmb(void);
270 
271 
272 /* Implementations */
l4_barrier(void)273 L4_INLINE void l4_barrier(void)
274 {
275   __asm__ __volatile__ ("" : : : "memory");
276 }
277 
l4_mb(void)278 L4_INLINE void l4_mb(void)
279 {
280   __asm__ __volatile__ ("" : : : "memory");
281 }
282 
l4_wmb(void)283 L4_INLINE void l4_wmb(void)
284 {
285   __asm__ __volatile__ ("" : : : "memory");
286 }
287 #endif
288 
289 /*@}*/
290 
291 #endif /* !__L4_COMPILER_H__ */
292