Commit | Line | Data |
---|---|---|
f611d0c3 MD |
1 | // SPDX-License-Identifier: MIT |
2 | /* | |
3 | * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
4 | */ | |
5 | ||
67337c4a MD |
6 | #ifndef _SIDE_MACROS_H |
7 | #define _SIDE_MACROS_H | |
f611d0c3 | 8 | |
6e46f5e6 | 9 | #include <stddef.h> |
8e87e437 | 10 | #include <limits.h> |
6e46f5e6 | 11 | |
f611d0c3 MD |
12 | /* Helper macros */ |
13 | ||
67337c4a | 14 | #define SIDE_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) |
f611d0c3 MD |
15 | |
16 | /* | |
67337c4a | 17 | * Compound literals with static storage are needed by SIDE |
f611d0c3 MD |
18 | * instrumentation. |
19 | * Compound literals are part of the C99 and C11 standards, but not | |
20 | * part of the C++ standards. They are supported by most C++ compilers | |
21 | * though. | |
22 | * | |
23 | * Example use: | |
24 | * static struct mystruct *var = LTTNG_UST_COMPOUND_LITERAL(struct mystruct, { 1, 2, 3 }); | |
25 | */ | |
67337c4a | 26 | #define SIDE_COMPOUND_LITERAL(type, ...) (type[]) { __VA_ARGS__ } |
f611d0c3 | 27 | |
67337c4a MD |
28 | #define side_likely(x) __builtin_expect(!!(x), 1) |
29 | #define side_unlikely(x) __builtin_expect(!!(x), 0) | |
f611d0c3 | 30 | |
67337c4a | 31 | #define SIDE_PARAM(...) __VA_ARGS__ |
f611d0c3 | 32 | |
d0ee69ff MD |
33 | /* |
34 | * SIDE_PARAM_SELECT_ARG1 | |
35 | * | |
36 | * Select second argument. Use inside macros to implement optional last | |
37 | * macro argument, such as: | |
38 | * | |
39 | * #define macro(_a, _b, _c, _optional...) \ | |
40 | * SIDE_PARAM_SELECT_ARG1(_, ##_optional, do_default_macro()) | |
41 | * | |
42 | * This macro is far from pretty, but attempts to create a cleaner layer | |
43 | * on top fails for various reasons: | |
44 | * | |
45 | * - The libside API needs to use the default argument selection as an | |
46 | * argument to itself (recursively), e.g. for fields and for types, so | |
47 | * using the argument selection within an extra layer of macro fails | |
48 | * because the extra layer cannot expand recursively. | |
49 | * - Attempts to make the extra layer of macro support recursion through | |
50 | * another layer of macros which expands all arguments failed because | |
51 | * the optional argument may contain commas, and is therefore expanded | |
52 | * into multiple arguments before argument selection, which fails to | |
53 | * select the optional argument content after its first comma. | |
54 | */ | |
55 | #define SIDE_PARAM_SELECT_ARG1(_arg0, _arg1, ...) _arg1 | |
56 | ||
b59abc69 | 57 | /* |
67337c4a | 58 | * side_container_of - Get the address of an object containing a field. |
b59abc69 MD |
59 | * |
60 | * @ptr: pointer to the field. | |
61 | * @type: type of the object. | |
62 | * @member: name of the field within the object. | |
63 | */ | |
67337c4a | 64 | #define side_container_of(ptr, type, member) \ |
b59abc69 MD |
65 | __extension__ \ |
66 | ({ \ | |
67 | const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \ | |
68 | (type *)((char *)__ptr - offsetof(type, member)); \ | |
69 | }) | |
70 | ||
67337c4a | 71 | #define side_struct_field_sizeof(_struct, _field) \ |
88bab79c | 72 | sizeof(((_struct * )NULL)->_field) |
8e87e437 | 73 | |
f61301bb | 74 | #if defined(__SIZEOF_LONG__) |
d78c8f2d | 75 | # define SIDE_BITS_PER_LONG (__SIZEOF_LONG__ * 8) |
f61301bb | 76 | #elif defined(_LP64) |
d78c8f2d | 77 | # define SIDE_BITS_PER_LONG 64 |
f61301bb | 78 | #else |
d78c8f2d | 79 | # define SIDE_BITS_PER_LONG 32 |
f61301bb MD |
80 | #endif |
81 | ||
67337c4a | 82 | #define SIDE_PACKED __attribute__((packed)) |
de4ae6e8 | 83 | |
326c676c MD |
84 | /* |
85 | * The side_ptr macros allow defining a pointer type which is suitable | |
86 | * for use by 32-bit and 64-bit kernels without compatibility code, | |
87 | * while preserving information about the pointer type. | |
88 | * | |
89 | * Those pointers are stored as 64-bit integers, and the type of the | |
90 | * actual pointer is kept alongside with the 64-bit pointer value in a | |
91 | * 0-len array within a union. | |
92 | * | |
93 | * uintptr_t will fit within a uint64_t except on architectures with | |
94 | * 128-bit pointers. This provides fixed-size pointers on architectures | |
95 | * with pointer size of 64-bit or less. Architectures with larger | |
96 | * pointer size will have to handle the ABI offset specifics explicitly. | |
97 | */ | |
98 | #if (__SIZEOF_POINTER__ <= 8) | |
99 | # define side_ptr_t(_type) \ | |
100 | union { \ | |
101 | uint64_t v; \ | |
102 | _type *t[0]; \ | |
103 | } | |
104 | # define side_ptr_get(_field) \ | |
105 | ((__typeof__((_field).t[0]))(uintptr_t)(_field).v) | |
106 | # define side_ptr_set(_field, _ptr) \ | |
107 | do { \ | |
108 | (_field).v = (uint64_t)(uintptr_t)(_ptr); \ | |
109 | } while (0) | |
110 | #else | |
111 | # define side_ptr_t(_type) \ | |
112 | union { \ | |
113 | uintptr_t v; \ | |
114 | _type *t[0]; \ | |
115 | } | |
116 | # define side_ptr_get(_field) \ | |
117 | ((__typeof__((_field).t[0]))(_field).v) | |
118 | # define side_ptr_set(_field, _ptr) \ | |
119 | do { \ | |
120 | (_field).v = (uintptr_t)(_ptr); \ | |
121 | } while (0) | |
122 | #endif | |
123 | ||
053076a0 | 124 | #define SIDE_PTR_INIT(...) { .v = (uintptr_t) (__VA_ARGS__) } |
0e2cd351 | 125 | |
67337c4a | 126 | #endif /* _SIDE_MACROS_H */ |