Commit | Line | Data |
---|---|---|
1c196845 MJ |
1 | // SPDX-FileCopyrightText: 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
2 | // | |
3 | // SPDX-License-Identifier: MIT | |
eae3c729 MJ |
4 | |
5 | #ifndef _LTTNG_UST_UTILS_H | |
6 | #define _LTTNG_UST_UTILS_H | |
7 | ||
8 | #include <stdio.h> | |
9 | #include <stdlib.h> | |
10 | #include <urcu/compiler.h> | |
11 | ||
12 | /* For lttng_ust_is_integer_type */ | |
13 | #if defined (__cplusplus) | |
14 | #include <type_traits> | |
15 | #endif | |
16 | ||
17 | ||
18 | /** | |
19 | * lttng_ust_stringify - convert a literal value to a C string | |
20 | */ | |
21 | #define __lttng_ust_stringify1(x) #x | |
22 | #define lttng_ust_stringify(x) __lttng_ust_stringify1(x) | |
23 | ||
24 | /** | |
25 | * lttng_ust_is_signed_type - check if type is signed | |
26 | * | |
27 | * Returns true if the type of @type is signed. | |
28 | */ | |
cd933410 MJ |
29 | #if defined(__cplusplus) |
30 | #define lttng_ust_is_signed_type(type) (std::is_signed<type>::value) | |
31 | #else | |
32 | #define lttng_ust_is_signed_type(type) ((type) -1 < (type) 1) | |
33 | #endif | |
eae3c729 MJ |
34 | |
35 | ||
36 | /** | |
37 | * lttng_ust_is_integer_type - check if type is an integer | |
38 | * | |
39 | * Returns true if the type of @type is an integer. | |
40 | */ | |
41 | #if defined(__cplusplus) | |
42 | #define lttng_ust_is_integer_type(type) (std::is_integral<type>::value) | |
43 | #else | |
44 | #define lttng_ust_is_integer_type(type) \ | |
45 | (__builtin_types_compatible_p(type, _Bool) || \ | |
46 | __builtin_types_compatible_p(type, char) || \ | |
d465835d | 47 | __builtin_types_compatible_p(type, signed char) || \ |
eae3c729 MJ |
48 | __builtin_types_compatible_p(type, unsigned char) || \ |
49 | __builtin_types_compatible_p(type, short) || \ | |
50 | __builtin_types_compatible_p(type, unsigned short) || \ | |
51 | __builtin_types_compatible_p(type, int) || \ | |
52 | __builtin_types_compatible_p(type, unsigned int) || \ | |
53 | __builtin_types_compatible_p(type, long) || \ | |
54 | __builtin_types_compatible_p(type, unsigned long) || \ | |
55 | __builtin_types_compatible_p(type, long long) || \ | |
56 | __builtin_types_compatible_p(type, unsigned long long)) | |
57 | #endif | |
58 | ||
62eb004c MD |
59 | /** |
60 | * lttng_ust_is_pointer_type - check if type is a pointer | |
61 | * | |
62 | * Returns true if the type of @type is a pointer. | |
f04f60a5 MD |
63 | * |
64 | * Note: The C implementation of lttng_ust_is_pointer_type uses pointer | |
65 | * arithmetic, which does not work on opaque pointer types. | |
62eb004c MD |
66 | */ |
67 | #if defined(__cplusplus) | |
68 | #define lttng_ust_is_pointer_type(type) (std::is_pointer<type>::value) | |
69 | #else | |
70 | /* The difference between two pointers is an integer. */ | |
71 | #define lttng_ust_is_pointer_type(type) \ | |
a9bd7249 | 72 | (lttng_ust_is_integer_type(typeof(((type)1 - (type)1))) && !lttng_ust_is_integer_type(type)) |
62eb004c MD |
73 | #endif |
74 | ||
75 | ||
eae3c729 | 76 | /** |
10937ee5 | 77 | * lttng_ust_field_array_element_type_is_supported - |
eae3c729 | 78 | * |
10937ee5 | 79 | * Adds a compilation assertion that array and sequence fields declared by the |
62eb004c | 80 | * user are of an integral or pointer type. |
eae3c729 | 81 | */ |
10937ee5 | 82 | #define lttng_ust_field_array_element_type_is_supported(type, item) \ |
62eb004c MD |
83 | lttng_ust_static_assert(lttng_ust_is_integer_type(type) || lttng_ust_is_pointer_type(type), \ |
84 | "Non-integer, non-pointer type `" #item "` not supported as element of LTTNG_UST_FIELD_ARRAY or LTTNG_UST_FIELD_SEQUENCE", \ | |
10937ee5 | 85 | Non_integer_type__##item##__not_supported_as_element_of_LTTNG_UST_FIELD_ARRAY_or_LTTNG_UST_FIELD_SEQUENCE) |
eae3c729 MJ |
86 | |
87 | ||
88 | /** | |
89 | * lttng_ust_runtime_bug_on - check condition at runtime | |
90 | * @condition: the condition which should be false. | |
91 | * | |
92 | * If the condition is true, a BUG will be triggered at runtime. | |
93 | */ | |
94 | #define lttng_ust_runtime_bug_on(condition) \ | |
95 | do { \ | |
96 | if (caa_unlikely(condition)) { \ | |
97 | fprintf(stderr, \ | |
98 | "LTTng BUG in file %s, line %d.\n", \ | |
99 | __FILE__, __LINE__); \ | |
100 | exit(EXIT_FAILURE); \ | |
101 | } \ | |
102 | } while (0) | |
103 | ||
104 | ||
105 | /** | |
106 | * lttng_ust_build_bug_on - check condition at build | |
107 | * @condition: the condition which should be false. | |
108 | * | |
109 | * If the condition is true, the compiler will generate a build error. | |
110 | */ | |
111 | #define lttng_ust_build_bug_on(condition) \ | |
112 | ((void) sizeof(char[-!!(condition)])) | |
113 | ||
114 | ||
115 | /** | |
116 | * lttng_ust_build_runtime_bug_on - check condition at build (if constant) or runtime | |
117 | * @condition: the condition which should be false. | |
118 | * | |
119 | * If the condition is a constant and true, the compiler will generate a build | |
120 | * error. If the condition is not constant, a BUG will be triggered at runtime | |
121 | * if the condition is ever true. If the condition is constant and false, no | |
122 | * code is emitted. | |
123 | */ | |
124 | #define lttng_ust_build_runtime_bug_on(condition) \ | |
125 | do { \ | |
126 | if (__builtin_constant_p(condition)) \ | |
127 | lttng_ust_build_bug_on(condition); \ | |
128 | else \ | |
129 | lttng_ust_runtime_bug_on(condition); \ | |
130 | } while (0) | |
131 | ||
132 | ||
133 | /** | |
134 | * lttng_ust_offset_align - Calculate the offset needed to align an object on | |
135 | * its natural alignment towards higher addresses. | |
136 | * @align_drift: object offset from an "alignment"-aligned address. | |
137 | * @alignment: natural object alignment. Must be non-zero, power of 2. | |
138 | * | |
139 | * Returns the offset that must be added to align towards higher | |
140 | * addresses. | |
141 | */ | |
142 | #define lttng_ust_offset_align(align_drift, alignment) \ | |
143 | ({ \ | |
144 | lttng_ust_build_runtime_bug_on((alignment) == 0 \ | |
145 | || ((alignment) & ((alignment) - 1))); \ | |
146 | (((alignment) - (align_drift)) & ((alignment) - 1)); \ | |
147 | }) | |
148 | ||
149 | ||
150 | /** | |
151 | * lttng_ust_offset_align_floor - Calculate the offset needed to align an | |
152 | * object on its natural alignment towards lower addresses. | |
153 | * @align_drift: object offset from an "alignment"-aligned address. | |
154 | * @alignment: natural object alignment. Must be non-zero, power of 2. | |
155 | * | |
2fbda51c | 156 | * Returns the offset that must be subtracted to align towards lower addresses. |
eae3c729 MJ |
157 | */ |
158 | #define lttng_ust_offset_align_floor(align_drift, alignment) \ | |
159 | ({ \ | |
160 | lttng_ust_build_runtime_bug_on((alignment) == 0 \ | |
161 | || ((alignment) & ((alignment) - 1))); \ | |
162 | (((align_drift) - (alignment)) & ((alignment) - 1)); \ | |
163 | }) | |
164 | ||
165 | #endif /* _LTTNG_UST_UTILS_H */ |