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