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 | */ | |
31 | #define lttng_ust_is_signed_type(type) ((type) -1 < (type) 1) | |
32 | ||
33 | ||
34 | /** | |
35 | * lttng_ust_is_integer_type - check if type is an integer | |
36 | * | |
37 | * Returns true if the type of @type is an integer. | |
38 | */ | |
39 | #if defined(__cplusplus) | |
40 | #define lttng_ust_is_integer_type(type) (std::is_integral<type>::value) | |
41 | #else | |
42 | #define lttng_ust_is_integer_type(type) \ | |
43 | (__builtin_types_compatible_p(type, _Bool) || \ | |
44 | __builtin_types_compatible_p(type, char) || \ | |
45 | __builtin_types_compatible_p(type, unsigned char) || \ | |
46 | __builtin_types_compatible_p(type, short) || \ | |
47 | __builtin_types_compatible_p(type, unsigned short) || \ | |
48 | __builtin_types_compatible_p(type, int) || \ | |
49 | __builtin_types_compatible_p(type, unsigned int) || \ | |
50 | __builtin_types_compatible_p(type, long) || \ | |
51 | __builtin_types_compatible_p(type, unsigned long) || \ | |
52 | __builtin_types_compatible_p(type, long long) || \ | |
53 | __builtin_types_compatible_p(type, unsigned long long)) | |
54 | #endif | |
55 | ||
56 | /** | |
57 | * lttng_ust_ctf_array_element_type_is_supported - | |
58 | * | |
59 | * Adds a compilation assertion that CTF arrays and sequences declared by the | |
60 | * user are of an integral type. | |
61 | */ | |
62 | #define lttng_ust_ctf_array_element_type_is_supported(type, item) \ | |
63 | lttng_static_assert(lttng_ust_is_integer_type(type), \ | |
64 | "Non-integer type `" #item "` not supported as element of CTF_ARRAY or CTF_SEQUENCE", \ | |
65 | Non_integer_type__##item##__not_supported_as_element_of_CTF_ARRAY_or_CTF_SEQUENCE); | |
66 | ||
67 | ||
68 | /** | |
69 | * lttng_ust_runtime_bug_on - check condition at runtime | |
70 | * @condition: the condition which should be false. | |
71 | * | |
72 | * If the condition is true, a BUG will be triggered at runtime. | |
73 | */ | |
74 | #define lttng_ust_runtime_bug_on(condition) \ | |
75 | do { \ | |
76 | if (caa_unlikely(condition)) { \ | |
77 | fprintf(stderr, \ | |
78 | "LTTng BUG in file %s, line %d.\n", \ | |
79 | __FILE__, __LINE__); \ | |
80 | exit(EXIT_FAILURE); \ | |
81 | } \ | |
82 | } while (0) | |
83 | ||
84 | ||
85 | /** | |
86 | * lttng_ust_build_bug_on - check condition at build | |
87 | * @condition: the condition which should be false. | |
88 | * | |
89 | * If the condition is true, the compiler will generate a build error. | |
90 | */ | |
91 | #define lttng_ust_build_bug_on(condition) \ | |
92 | ((void) sizeof(char[-!!(condition)])) | |
93 | ||
94 | ||
95 | /** | |
96 | * lttng_ust_build_runtime_bug_on - check condition at build (if constant) or runtime | |
97 | * @condition: the condition which should be false. | |
98 | * | |
99 | * If the condition is a constant and true, the compiler will generate a build | |
100 | * error. If the condition is not constant, a BUG will be triggered at runtime | |
101 | * if the condition is ever true. If the condition is constant and false, no | |
102 | * code is emitted. | |
103 | */ | |
104 | #define lttng_ust_build_runtime_bug_on(condition) \ | |
105 | do { \ | |
106 | if (__builtin_constant_p(condition)) \ | |
107 | lttng_ust_build_bug_on(condition); \ | |
108 | else \ | |
109 | lttng_ust_runtime_bug_on(condition); \ | |
110 | } while (0) | |
111 | ||
112 | ||
113 | /** | |
114 | * lttng_ust_offset_align - Calculate the offset needed to align an object on | |
115 | * its natural alignment towards higher addresses. | |
116 | * @align_drift: object offset from an "alignment"-aligned address. | |
117 | * @alignment: natural object alignment. Must be non-zero, power of 2. | |
118 | * | |
119 | * Returns the offset that must be added to align towards higher | |
120 | * addresses. | |
121 | */ | |
122 | #define lttng_ust_offset_align(align_drift, alignment) \ | |
123 | ({ \ | |
124 | lttng_ust_build_runtime_bug_on((alignment) == 0 \ | |
125 | || ((alignment) & ((alignment) - 1))); \ | |
126 | (((alignment) - (align_drift)) & ((alignment) - 1)); \ | |
127 | }) | |
128 | ||
129 | ||
130 | /** | |
131 | * lttng_ust_offset_align_floor - Calculate the offset needed to align an | |
132 | * object on its natural alignment towards lower addresses. | |
133 | * @align_drift: object offset from an "alignment"-aligned address. | |
134 | * @alignment: natural object alignment. Must be non-zero, power of 2. | |
135 | * | |
136 | * Returns the offset that must be substracted to align towards lower addresses. | |
137 | */ | |
138 | #define lttng_ust_offset_align_floor(align_drift, alignment) \ | |
139 | ({ \ | |
140 | lttng_ust_build_runtime_bug_on((alignment) == 0 \ | |
141 | || ((alignment) & ((alignment) - 1))); \ | |
142 | (((align_drift) - (alignment)) & ((alignment) - 1)); \ | |
143 | }) | |
144 | ||
145 | #endif /* _LTTNG_UST_UTILS_H */ |