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 | ||
61 | /** | |
10937ee5 | 62 | * lttng_ust_field_array_element_type_is_supported - |
eae3c729 | 63 | * |
10937ee5 | 64 | * Adds a compilation assertion that array and sequence fields declared by the |
eae3c729 MJ |
65 | * user are of an integral type. |
66 | */ | |
10937ee5 | 67 | #define lttng_ust_field_array_element_type_is_supported(type, item) \ |
3a98c813 | 68 | lttng_ust_static_assert(lttng_ust_is_integer_type(type), \ |
10937ee5 MJ |
69 | "Non-integer type `" #item "` not supported as element of LTTNG_UST_FIELD_ARRAY or LTTNG_UST_FIELD_SEQUENCE", \ |
70 | Non_integer_type__##item##__not_supported_as_element_of_LTTNG_UST_FIELD_ARRAY_or_LTTNG_UST_FIELD_SEQUENCE) | |
eae3c729 MJ |
71 | |
72 | ||
73 | /** | |
74 | * lttng_ust_runtime_bug_on - check condition at runtime | |
75 | * @condition: the condition which should be false. | |
76 | * | |
77 | * If the condition is true, a BUG will be triggered at runtime. | |
78 | */ | |
79 | #define lttng_ust_runtime_bug_on(condition) \ | |
80 | do { \ | |
81 | if (caa_unlikely(condition)) { \ | |
82 | fprintf(stderr, \ | |
83 | "LTTng BUG in file %s, line %d.\n", \ | |
84 | __FILE__, __LINE__); \ | |
85 | exit(EXIT_FAILURE); \ | |
86 | } \ | |
87 | } while (0) | |
88 | ||
89 | ||
90 | /** | |
91 | * lttng_ust_build_bug_on - check condition at build | |
92 | * @condition: the condition which should be false. | |
93 | * | |
94 | * If the condition is true, the compiler will generate a build error. | |
95 | */ | |
96 | #define lttng_ust_build_bug_on(condition) \ | |
97 | ((void) sizeof(char[-!!(condition)])) | |
98 | ||
99 | ||
100 | /** | |
101 | * lttng_ust_build_runtime_bug_on - check condition at build (if constant) or runtime | |
102 | * @condition: the condition which should be false. | |
103 | * | |
104 | * If the condition is a constant and true, the compiler will generate a build | |
105 | * error. If the condition is not constant, a BUG will be triggered at runtime | |
106 | * if the condition is ever true. If the condition is constant and false, no | |
107 | * code is emitted. | |
108 | */ | |
109 | #define lttng_ust_build_runtime_bug_on(condition) \ | |
110 | do { \ | |
111 | if (__builtin_constant_p(condition)) \ | |
112 | lttng_ust_build_bug_on(condition); \ | |
113 | else \ | |
114 | lttng_ust_runtime_bug_on(condition); \ | |
115 | } while (0) | |
116 | ||
117 | ||
118 | /** | |
119 | * lttng_ust_offset_align - Calculate the offset needed to align an object on | |
120 | * its natural alignment towards higher addresses. | |
121 | * @align_drift: object offset from an "alignment"-aligned address. | |
122 | * @alignment: natural object alignment. Must be non-zero, power of 2. | |
123 | * | |
124 | * Returns the offset that must be added to align towards higher | |
125 | * addresses. | |
126 | */ | |
127 | #define lttng_ust_offset_align(align_drift, alignment) \ | |
128 | ({ \ | |
129 | lttng_ust_build_runtime_bug_on((alignment) == 0 \ | |
130 | || ((alignment) & ((alignment) - 1))); \ | |
131 | (((alignment) - (align_drift)) & ((alignment) - 1)); \ | |
132 | }) | |
133 | ||
134 | ||
135 | /** | |
136 | * lttng_ust_offset_align_floor - Calculate the offset needed to align an | |
137 | * object on its natural alignment towards lower addresses. | |
138 | * @align_drift: object offset from an "alignment"-aligned address. | |
139 | * @alignment: natural object alignment. Must be non-zero, power of 2. | |
140 | * | |
2fbda51c | 141 | * Returns the offset that must be subtracted to align towards lower addresses. |
eae3c729 MJ |
142 | */ |
143 | #define lttng_ust_offset_align_floor(align_drift, alignment) \ | |
144 | ({ \ | |
145 | lttng_ust_build_runtime_bug_on((alignment) == 0 \ | |
146 | || ((alignment) & ((alignment) - 1))); \ | |
147 | (((align_drift) - (alignment)) & ((alignment) - 1)); \ | |
148 | }) | |
149 | ||
150 | #endif /* _LTTNG_UST_UTILS_H */ |