Home | History | Annotate | Line # | Download | only in urcu
      1 // SPDX-FileCopyrightText: 2009 Mathieu Desnoyers <mathieu.desnoyers (at) efficios.com>
      2 //
      3 // SPDX-License-Identifier: LGPL-2.1-or-later
      4 
      5 #ifndef _URCU_COMPILER_H
      6 #define _URCU_COMPILER_H
      7 
      8 /*
      9  * Compiler definitions.
     10  */
     11 
     12 #include <stddef.h>	/* for offsetof */
     13 
     14 #if defined __cplusplus
     15 # include <type_traits>	/* for std::remove_cv */
     16 #endif
     17 
     18 #include <urcu/config.h>
     19 
     20 #define caa_likely(x)	__builtin_expect(!!(x), 1)
     21 #define caa_unlikely(x)	__builtin_expect(!!(x), 0)
     22 
     23 #ifdef CONFIG_RCU_USE_ATOMIC_BUILTINS
     24 #  define cmm_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
     25 #else
     26 #  define cmm_barrier() __asm__ __volatile__ ("" : : : "memory")
     27 #endif
     28 
     29 /*
     30  * Instruct the compiler to perform only a single access to a variable
     31  * (prohibits merging and refetching). The compiler is also forbidden to reorder
     32  * successive instances of CMM_ACCESS_ONCE(), but only when the compiler is aware of
     33  * particular ordering. Compiler ordering can be ensured, for example, by
     34  * putting two CMM_ACCESS_ONCE() in separate C statements.
     35  *
     36  * This macro does absolutely -nothing- to prevent the CPU from reordering,
     37  * merging, or refetching absolutely anything at any time.  Its main intended
     38  * use is to mediate communication between process-level code and irq/NMI
     39  * handlers, all running on the same CPU.
     40  */
     41 #define CMM_ACCESS_ONCE(x)	(*(__volatile__  __typeof__(x) *)&(x))
     42 
     43 /*
     44  * If the toolchain support the C11 memory model, define the private macro
     45  * _CMM_TOOLCHAIN_SUPPORT_C11_MM.
     46  */
     47 #if ((defined (__cplusplus) && __cplusplus >= 201103L) ||		\
     48 	(defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L))
     49 # define _CMM_TOOLCHAIN_SUPPORT_C11_MM
     50 #elif defined(CONFIG_RCU_USE_ATOMIC_BUILTINS)
     51 #  error "URCU was configured to use atomic builtins, but this toolchain does not support them."
     52 #endif
     53 
     54 /* Make the optimizer believe the variable can be manipulated arbitrarily. */
     55 #define _CMM_OPTIMIZER_HIDE_VAR(var)		\
     56 	__asm__ ("" : "+r" (var))
     57 
     58 #ifndef caa_max
     59 #define caa_max(a,b) ((a)>(b)?(a):(b))
     60 #endif
     61 
     62 #ifndef caa_min
     63 #define caa_min(a,b) ((a)<(b)?(a):(b))
     64 #endif
     65 
     66 #if defined(__SIZEOF_LONG__)
     67 #define CAA_BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
     68 #elif defined(_LP64)
     69 #define CAA_BITS_PER_LONG	64
     70 #else
     71 #define CAA_BITS_PER_LONG	32
     72 #endif
     73 
     74 /*
     75  * caa_container_of - Get the address of an object containing a field.
     76  *
     77  * @ptr: pointer to the field.
     78  * @type: type of the object.
     79  * @member: name of the field within the object.
     80  */
     81 #define caa_container_of(ptr, type, member)				\
     82 	__extension__							\
     83 	({								\
     84 		const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \
     85 		(type *)((char *)__ptr - offsetof(type, member));	\
     86 	})
     87 
     88 /*
     89  * caa_container_of_check_null - Get the address of an object containing a field.
     90  *
     91  * @ptr: pointer to the field.
     92  * @type: type of the object.
     93  * @member: name of the field within the object.
     94  *
     95  * Return the address of the object containing the field. Return NULL if
     96  * @ptr is NULL.
     97  */
     98 #define caa_container_of_check_null(ptr, type, member)			\
     99 	__extension__							\
    100 	({								\
    101 		const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \
    102 		(__ptr) ? (type *)((char *)__ptr - offsetof(type, member)) : NULL; \
    103 	})
    104 
    105 #define CAA_BUILD_BUG_ON_ZERO(cond) (sizeof(struct { int:-!!(cond); }))
    106 #define CAA_BUILD_BUG_ON(cond) ((void)CAA_BUILD_BUG_ON_ZERO(cond))
    107 
    108 /*
    109  * __rcu is an annotation that documents RCU pointer accesses that need
    110  * to be protected by a read-side critical section. Eventually, a static
    111  * checker will be able to use this annotation to detect incorrect RCU
    112  * usage.
    113  */
    114 #define __rcu
    115 
    116 #ifdef __cplusplus
    117 #define URCU_FORCE_CAST(_type, arg)	(reinterpret_cast<typename std::remove_cv<_type>::type>(arg))
    118 #else
    119 #define URCU_FORCE_CAST(type, arg)	((type) (arg))
    120 #endif
    121 
    122 #define caa_is_signed_type(type)	((type) -1 < (type) 0)
    123 
    124 /*
    125  * Cast to unsigned long, sign-extending if @v is signed.
    126  * Note: casting to a larger type or to same type size keeps the sign of
    127  * the expression being cast (see C99 6.3.1.3).
    128  */
    129 #define caa_cast_long_keep_sign(v)	((unsigned long) (v))
    130 
    131 #if defined (__GNUC__) \
    132 	&& ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)	\
    133 		|| __GNUC__ >= 5)
    134 #define CDS_DEPRECATED(msg)	\
    135 	__attribute__((deprecated(msg)))
    136 #else
    137 #define CDS_DEPRECATED(msg)	\
    138 	__attribute__((deprecated))
    139 #endif
    140 
    141 #define CAA_ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0]))
    142 
    143 /*
    144  * URCU_GCC_VERSION is used to blacklist specific GCC versions with known
    145  * bugs, clang also defines these macros to an equivalent GCC version it
    146  * claims to support, so exclude it.
    147  */
    148 #if defined(__GNUC__) && !defined(__clang__)
    149 # define URCU_GCC_VERSION	(__GNUC__ * 10000 \
    150 				+ __GNUC_MINOR__ * 100 \
    151 				+ __GNUC_PATCHLEVEL__)
    152 #endif
    153 
    154 #ifdef __cplusplus
    155 #define caa_unqual_scalar_typeof(x)					\
    156 	std::remove_cv<std::remove_reference<decltype(x)>::type>::type
    157 #else
    158 #define caa_scalar_type_to_expr(type)					\
    159 	unsigned type: (unsigned type)0,				\
    160 	signed type: (signed type)0
    161 
    162 /*
    163  * Use C11 _Generic to express unqualified type from expression. This removes
    164  * volatile qualifier from expression type.
    165  */
    166 #define caa_unqual_scalar_typeof(x)					\
    167 	__typeof__(							\
    168 		_Generic((x),						\
    169 			char: (char)0,					\
    170 			caa_scalar_type_to_expr(char),			\
    171 			caa_scalar_type_to_expr(short),		\
    172 			caa_scalar_type_to_expr(int),			\
    173 			caa_scalar_type_to_expr(long),			\
    174 			caa_scalar_type_to_expr(long long),		\
    175 			default: (x)					\
    176 		)							\
    177 	)
    178 #endif
    179 
    180 /*
    181  * Allow user to manually define CMM_SANITIZE_THREAD if their toolchain is not
    182  * supported by this check.
    183  */
    184 #ifndef CMM_SANITIZE_THREAD
    185 # if defined(__GNUC__) && defined(__SANITIZE_THREAD__)
    186 #  define CMM_SANITIZE_THREAD
    187 # elif defined(__clang__) && defined(__has_feature)
    188 #  if __has_feature(thread_sanitizer)
    189 #   define CMM_SANITIZE_THREAD
    190 #  endif
    191 # endif
    192 #endif	/* !CMM_SANITIZE_THREAD */
    193 
    194 /*
    195  * Helper to add the volatile qualifier to a pointer.
    196  *
    197  * This is used to enforce volatile accesses even when using atomic
    198  * builtins. Indeed, C11 atomic operations all work on volatile memory
    199  * accesses, but this is not documented for compiler atomic builtins.
    200  *
    201  * This could prevent certain classes of optimization from the compiler such
    202  * as load/store fusing.
    203  */
    204 #if defined __cplusplus
    205 template <typename T>
    206 volatile T cmm_cast_volatile(T t)
    207 {
    208     return static_cast<volatile T>(t);
    209 }
    210 #else
    211 #  define cmm_cast_volatile(ptr)			\
    212 	__extension__					\
    213 	({						\
    214 		(volatile __typeof__(ptr))(ptr);	\
    215 	})
    216 #endif
    217 
    218 /*
    219  * Compile time assertion.
    220  * - predicate: boolean expression to evaluate,
    221  * - msg: string to print to the user on failure when `static_assert()` is
    222  *   supported,
    223  * - c_identifier_msg: message to be included in the typedef to emulate a
    224  *   static assertion. This parameter must be a valid C identifier as it will
    225  *   be used as a typedef name.
    226  */
    227 #ifdef __cplusplus
    228 #define urcu_static_assert(predicate, msg, c_identifier_msg)  \
    229 	static_assert(predicate, msg)
    230 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
    231 #define urcu_static_assert(predicate, msg, c_identifier_msg)  \
    232 	_Static_assert(predicate, msg)
    233 #else
    234 /*
    235  * Evaluates the predicate and emit a compilation error on failure.
    236  *
    237  * If the predicate evaluates to true, this macro emits a function
    238  * prototype with an argument type which is an array of size 0.
    239  *
    240  * If the predicate evaluates to false, this macro emits a function
    241  * prototype with an argument type which is an array of negative size
    242  * which is invalid in C and forces a compiler error. The
    243  * c_identifier_msg parameter is used as the argument identifier so it
    244  * is printed to the user when the error is reported.
    245  */
    246 #define urcu_static_assert(predicate, msg, c_identifier_msg)  \
    247 	void urcu_static_assert_proto(char c_identifier_msg[2*!!(predicate)-1])
    248 #endif
    249 
    250 #endif /* _URCU_COMPILER_H */
    251