Build fix: poll compatibility mode: zmalloc prototype changed
[lttng-tools.git] / src / common / macros.hpp
CommitLineData
990570ed 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
ab5be9fa 3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
990570ed 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
990570ed 6 *
990570ed
DG
7 */
8
9#ifndef _MACROS_H
10#define _MACROS_H
11
64803277
SM
12#include <common/compat/string.hpp>
13
93375aa6 14#include <stddef.h>
64803277 15#include <stdlib.h>
f6835b82 16#include <string.h>
64803277
SM
17
18#include <type_traits>
990570ed
DG
19
20/*
21 * Takes a pointer x and transform it so we can use it to access members
22 * without a function call. Here an example:
23 *
24 * #define GET_SIZE(x) LTTNG_REF(x)->size
25 *
26 * struct { int size; } s;
27 *
28 * printf("size : %d\n", GET_SIZE(&s));
29 *
30 * For this example we can't use something like this for compatibility purpose
31 * since this will fail:
32 *
33 * #define GET_SIZE(x) x->size;
34 *
35 * This is mostly use for the compatibility layer of lttng-tools. See
36 * poll/epoll for a good example. Since x can be on the stack or allocated
37 * memory using malloc(), we must use generic accessors for compat in order to
38 * *not* use a function to access members and not the variable name.
39 */
40#define LTTNG_REF(x) ((typeof(*x) *)(x))
41
64803277
SM
42#ifdef NDEBUG
43/*
44* Force usage of the assertion condition to prevent unused variable warnings
45* when `assert()` are disabled by the `NDEBUG` definition.
46*/
47# define LTTNG_ASSERT(_cond) ((void) sizeof((void) (_cond), 0))
48#else
49# include <assert.h>
50# define LTTNG_ASSERT(_cond) assert(_cond)
51#endif
52
990570ed
DG
53/*
54 * Memory allocation zeroed
55 */
64803277 56
4616a46c 57static inline
64803277
SM
58void *zmalloc_internal(size_t size)
59{
60 return calloc(1, size);
61}
62
63template <typename T>
64struct can_malloc
65{
66 static constexpr bool value = std::is_trivially_constructible<T>::value;
67};
68
69/*
70 * Malloc and zero-initialize an object of type T, asserting that T can be
71 * safely malloc-ed (is trivially constructible).
72 */
73template<typename T>
74T *zmalloc()
75{
76 static_assert (can_malloc<T>::value, "type can be malloc'ed");
77 return (T *) zmalloc_internal(sizeof(T));
78}
79
80/*
81 * Malloc and zero-initialize a buffer of size `size`, asserting that type T
82 * can be safely malloc-ed (is trivially constructible).
83 */
84template<typename T>
85T *zmalloc(size_t size)
86{
87 static_assert (can_malloc<T>::value, "type can be malloc'ed");
88 LTTNG_ASSERT(size >= sizeof(T));
89 return (T *) zmalloc_internal(size);
90}
91
92/*
93 * Malloc and zero-initialize an array of `nmemb` elements of type T,
94 * asserting that T can be safely malloc-ed (is trivially constructible).
95 */
96template<typename T>
97T *calloc(size_t nmemb)
98{
99 static_assert (can_malloc<T>::value, "type can be malloc'ed");
100 return (T *) zmalloc_internal(nmemb * sizeof(T));
101}
102
103/*
104 * Malloc an object of type T, asserting that T can be safely malloc-ed (is
105 * trivially constructible).
106 */
107template<typename T>
108T *malloc()
4616a46c 109{
64803277
SM
110 static_assert (can_malloc<T>::value, "type can be malloc'ed");
111 return (T *) malloc(sizeof(T));
4616a46c 112}
990570ed 113
64803277
SM
114/*
115 * Malloc a buffer of size `size`, asserting that type T can be safely
116 * malloc-ed (is trivially constructible).
117 */
118template<typename T>
119T *malloc(size_t size)
120{
121 static_assert (can_malloc<T>::value, "type can be malloc'ed");
122 return (T *) malloc(size);
123}
124
125/*
126 * Prevent using `free` on types that are non-POD.
127 *
128 * Declare a delete prototype of free if the parameter type is not safe to free
129 * (non-POD).
130 *
131 * If the parameter is a pointer to void, we can't check if what is pointed
132 * to is safe to free or not, as we don't know what is pointed to. Ideally,
133 * all calls to free would be with a typed pointer, but there are too many
134 * instances of passing a pointer to void to enforce that right now. So allow
135 * pointers to void, these will not be checked.
136 */
137
138template<typename T>
a8e336c2 139struct can_free
64803277 140{
a8e336c2 141 static constexpr bool value = std::is_trivially_destructible<T>::value || std::is_void<T>::value;
64803277
SM
142};
143
a8e336c2 144template<typename T, typename = typename std::enable_if<!can_free<T>::value>::type>
64803277
SM
145void free(T *p) = delete;
146
a8e336c2
SM
147template<typename T>
148struct can_memset
149{
150 static constexpr bool value = std::is_pod<T>::value || std::is_void<T>::value;
151};
152
153template <typename T, typename = typename std::enable_if<!can_memset<T>::value>::type>
154void *memset(T *s, int c, size_t n) = delete;
155
156template<typename T>
157struct can_memcpy
158{
159 static constexpr bool value = std::is_trivially_copyable<T>::value;
160};
161
162template <typename T, typename U,
163 typename = typename std::enable_if<!can_memcpy<T>::value>::type,
164 typename = typename std::enable_if<!can_memcpy<U>::value>::type>
165void *memcpy(T *d, const U *s, size_t n) = delete;
166
167template<typename T>
168struct can_memmove
169{
170 static constexpr bool value = std::is_trivially_copyable<T>::value;
171};
172
173template <typename T, typename U,
174 typename = typename std::enable_if<!can_memmove<T>::value>::type,
175 typename = typename std::enable_if<!can_memmove<U>::value>::type>
176void *memmove(T *d, const U *s, size_t n) = delete;
177
990570ed
DG
178#ifndef ARRAY_SIZE
179#define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0])))
180#endif
181
93375aa6
JG
182#ifndef container_of
183#define container_of(ptr, type, member) \
184 ({ \
185 const typeof(((type *)NULL)->member) * __ptr = (ptr); \
186 (type *)((char *)__ptr - offsetof(type, member)); \
187 })
188#endif
189
54c90d10
DG
190#ifndef LTTNG_PACKED
191#define LTTNG_PACKED __attribute__((__packed__))
192#endif
193
1405051a
FD
194#ifndef LTTNG_NO_SANITIZE_ADDRESS
195#if defined(__clang__) || defined (__GNUC__)
196#define LTTNG_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
197#else
198#define LTTNG_NO_SANITIZE_ADDRESS
199#endif
200#endif
201
f8f3885c
MD
202#define member_sizeof(type, field) sizeof(((type *) 0)->field)
203
a0377dfe 204#define ASSERT_LOCKED(lock) LTTNG_ASSERT(pthread_mutex_trylock(&lock))
48b7cdc2 205#define ASSERT_RCU_READ_LOCKED(lock) LTTNG_ASSERT(rcu_read_ongoing())
5e5c14ce 206
d22ad5f8
SM
207/* Attribute suitable to tag functions as having printf()-like arguments. */
208#define ATTR_FORMAT_PRINTF(_string_index, _first_to_check) \
209 __attribute__((format(printf, _string_index, _first_to_check)))
210
411b3154
SM
211/* Attribute suitable to tag functions as having strftime()-like arguments. */
212#define ATTR_FORMAT_STRFTIME(_string_index) \
213 __attribute__((format(strftime, _string_index, 0)))
214
d22ad5f8
SM
215/* Macros used to ignore specific compiler diagnostics. */
216
217#define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
218#define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
219
220#if defined(__clang__)
221 /* Clang */
222# define DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT
411b3154
SM
223# define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \
224 _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
942003e5 225# define DIAGNOSTIC_IGNORE_LOGICAL_OP
d22ad5f8
SM
226#else
227 /* GCC */
228# define DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT \
229 _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
411b3154
SM
230# define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \
231 _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
942003e5
MJ
232# define DIAGNOSTIC_IGNORE_LOGICAL_OP \
233 _Pragma("GCC diagnostic ignored \"-Wlogical-op\"")
d22ad5f8
SM
234#endif
235
d50d200a
SM
236/* Used to make specific C++ functions to C code. */
237#ifdef __cplusplus
238#define C_LINKAGE extern "C"
239#else
240#define C_LINKAGE
241#endif
242
f6835b82
MD
243/*
244 * lttng_strncpy returns 0 on success, or nonzero on failure.
245 * It checks that the @src string fits into @dst_len before performing
246 * the copy. On failure, no copy has been performed.
247 *
b25a5991
JG
248 * Assumes that 'src' is null-terminated.
249 *
f6835b82
MD
250 * dst_len includes the string's trailing NULL.
251 */
252static inline
253int lttng_strncpy(char *dst, const char *src, size_t dst_len)
254{
b25a5991 255 if (strlen(src) >= dst_len) {
f6835b82
MD
256 /* Fail since copying would result in truncation. */
257 return -1;
258 }
c3ef76cd 259 strcpy(dst, src);
f6835b82
MD
260 return 0;
261}
262
990570ed 263#endif /* _MACROS_H */
This page took 0.079148 seconds and 4 git commands to generate.