#ifndef __COMMON_XMALLOC_H__ #define __COMMON_XMALLOC_H__ #include #include #ifndef pr_err #error "Macro pr_err is needed." #endif #define __xalloc(op, size, ...) \ ({ \ void *___p = op(__VA_ARGS__); \ if (!___p) \ pr_err("%s: Can't allocate %li bytes\n", __func__, (long)(size)); \ ___p; \ }) #define xstrdup(str) __xalloc(strdup, strlen(str) + 1, str) #define xmalloc(size) __xalloc(malloc, size, size) #define xzalloc(size) __xalloc(calloc, size, 1, size) #define xrealloc(p, size) __xalloc(realloc, size, p, size) #define xfree(p) free(p) #define xrealloc_safe(pptr, size) \ ({ \ int __ret = -1; \ void *new = xrealloc(*pptr, size); \ if (new) { \ *pptr = new; \ __ret = 0; \ } \ __ret; \ }) #define xmemdup(ptr, size) \ ({ \ void *new = xmalloc(size); \ if (new) \ memcpy(new, ptr, size); \ new; \ }) #define memzero_p(p) memset(p, 0, sizeof(*p)) #define memzero(p, size) memset(p, 0, size) /* * Helper for allocating trees with single xmalloc. * This one advances the void *pointer on s bytes and * returns the previous value. Use like this * * m = xmalloc(total_size); * a = xptr_pull(&m, tree_root_t); * a->b = xptr_pull(&m, leaf_a_t); * a->c = xptr_pull(&m, leaf_c_t); * ... */ static inline void *xptr_pull_s(void **m, size_t s) { void *ret = (*m); (*m) += s; return ret; } #define xptr_pull(m, type) xptr_pull_s(m, sizeof(type)) #endif /* __CR_XMALLOC_H__ */