2 * Copyright (C) 2011 EfficiOS Inc.
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * SPDX-License-Identifier: GPL-2.0-only
12 #include <common/compat/string.hpp>
18 #include <type_traits>
21 * Takes a pointer x and transform it so we can use it to access members
22 * without a function call. Here an example:
24 * #define GET_SIZE(x) LTTNG_REF(x)->size
26 * struct { int size; } s;
28 * printf("size : %d\n", GET_SIZE(&s));
30 * For this example we can't use something like this for compatibility purpose
31 * since this will fail:
33 * #define GET_SIZE(x) x->size;
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.
40 #define LTTNG_REF(x) ((typeof(*x) *)(x))
44 * Force usage of the assertion condition to prevent unused variable warnings
45 * when `assert()` are disabled by the `NDEBUG` definition.
47 # define LTTNG_ASSERT(_cond) ((void) sizeof((void) (_cond), 0))
50 # define LTTNG_ASSERT(_cond) assert(_cond)
54 * Memory allocation zeroed
58 void *zmalloc_internal(size_t size)
60 return calloc(1, size);
66 static constexpr bool value = std::is_trivially_constructible<T>::value;
70 * Malloc and zero-initialize an object of type T, asserting that T can be
71 * safely malloc-ed (is trivially constructible).
76 static_assert (can_malloc<T>::value, "type can be malloc'ed");
77 return (T *) zmalloc_internal(sizeof(T));
81 * Malloc and zero-initialize a buffer of size `size`, asserting that type T
82 * can be safely malloc-ed (is trivially constructible).
85 T *zmalloc(size_t size)
87 static_assert (can_malloc<T>::value, "type can be malloc'ed");
88 LTTNG_ASSERT(size >= sizeof(T));
89 return (T *) zmalloc_internal(size);
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).
97 T *calloc(size_t nmemb)
99 static_assert (can_malloc<T>::value, "type can be malloc'ed");
100 return (T *) zmalloc_internal(nmemb * sizeof(T));
104 * Malloc an object of type T, asserting that T can be safely malloc-ed (is
105 * trivially constructible).
110 static_assert (can_malloc<T>::value, "type can be malloc'ed");
111 return (T *) malloc(sizeof(T));
115 * Malloc a buffer of size `size`, asserting that type T can be safely
116 * malloc-ed (is trivially constructible).
119 T *malloc(size_t size)
121 static_assert (can_malloc<T>::value, "type can be malloc'ed");
122 return (T *) malloc(size);
126 * Prevent using `free` on types that are non-POD.
128 * Declare a delete prototype of free if the parameter type is not safe to free
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.
139 struct is_pod_or_void
141 static constexpr bool value = std::is_pod<T>::value || std::is_void<T>::value;
144 template<typename T, typename = typename std::enable_if<!is_pod_or_void<T>::value>::type>
145 void free(T *p) = delete;
148 #define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0])))
152 #define container_of(ptr, type, member) \
154 const typeof(((type *)NULL)->member) * __ptr = (ptr); \
155 (type *)((char *)__ptr - offsetof(type, member)); \
160 #define LTTNG_PACKED __attribute__((__packed__))
163 #ifndef LTTNG_NO_SANITIZE_ADDRESS
164 #if defined(__clang__) || defined (__GNUC__)
165 #define LTTNG_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
167 #define LTTNG_NO_SANITIZE_ADDRESS
171 #define member_sizeof(type, field) sizeof(((type *) 0)->field)
173 #define ASSERT_LOCKED(lock) LTTNG_ASSERT(pthread_mutex_trylock(&lock))
174 #define ASSERT_RCU_READ_LOCKED(lock) LTTNG_ASSERT(rcu_read_ongoing())
176 /* Attribute suitable to tag functions as having printf()-like arguments. */
177 #define ATTR_FORMAT_PRINTF(_string_index, _first_to_check) \
178 __attribute__((format(printf, _string_index, _first_to_check)))
180 /* Attribute suitable to tag functions as having strftime()-like arguments. */
181 #define ATTR_FORMAT_STRFTIME(_string_index) \
182 __attribute__((format(strftime, _string_index, 0)))
184 /* Macros used to ignore specific compiler diagnostics. */
186 #define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
187 #define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
189 #if defined(__clang__)
191 # define DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT
192 # define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \
193 _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
194 # define DIAGNOSTIC_IGNORE_LOGICAL_OP
197 # define DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT \
198 _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
199 # define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \
200 _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
201 # define DIAGNOSTIC_IGNORE_LOGICAL_OP \
202 _Pragma("GCC diagnostic ignored \"-Wlogical-op\"")
205 /* Used to make specific C++ functions to C code. */
207 #define C_LINKAGE extern "C"
213 * lttng_strncpy returns 0 on success, or nonzero on failure.
214 * It checks that the @src string fits into @dst_len before performing
215 * the copy. On failure, no copy has been performed.
217 * Assumes that 'src' is null-terminated.
219 * dst_len includes the string's trailing NULL.
222 int lttng_strncpy(char *dst, const char *src, size_t dst_len)
224 if (strlen(src) >= dst_len) {
225 /* Fail since copying would result in truncation. */
232 #endif /* _MACROS_H */