Skip to content

Allocation Macros

include/mem/alloc_api_internal.h View source View on GitHub
#define alloc_params_with_defaults(_flags, _behavior, ...)
source
Expansion
#define alloc_params_with_defaults(_flags, _behavior, ...) \
    cc_wno_override_init_expr( \
        struct alloc_params, \
        ((struct alloc_params) {.flags = (_flags), \
                                .behavior = (_behavior), \
                                .priority = ALLOC_PRIORITY_DEFAULT, \
                                ##__VA_ARGS__}))
#define vfree_1(ptr)
source
Expansion
#define vfree_1(ptr) vfree_2((ptr), ALLOC_BEHAVIOR_DEFAULT)
#define vfree_2(ptr, bh)
source
Expansion
#define vfree_2(ptr, bh) vfree_full((ptr), (bh))
#define vfree(...)
source
Expansion
#define vfree(...) PP_CALL(vfree, __VA_ARGS__)
#define valloc(size, ...)
source
Expansion
#define valloc(size, ...) \
    valloc_full((size), alloc_params_with_defaults(ALLOC_FLAGS_DEFAULT, \
                                                   ALLOC_BEHAVIOR_DEFAULT, \
                                                   ##__VA_ARGS__))
#define valloc_aligned(size, align, ...)
source
Expansion
#define valloc_aligned(size, align, ...) \
    valloc_aligned_full((size), (align), \
                        alloc_params_with_defaults(ALLOC_FLAGS_DEFAULT, \
                                                   ALLOC_BEHAVIOR_DEFAULT, \
                                                   ##__VA_ARGS__))
#define VNEW_PTR(p)
source

struct foo *f = vnew(f, ALLOC_ZERO)

Expansion
#define VNEW_PTR(p) typeof(&*(p))
#define VNEW_CHECK(p)
source
Expansion
#define VNEW_CHECK(p) \
    static_assert( \
        __builtin_types_compatible_p(__typeof_unqual__(p), typeof(&*(p))), \
        "vnew: target must be a pointer lvalue, not an array"); \
    static_assert(!cc_generic((p), void * : 1, const void * : 1, \
                              volatile void * : 1, const volatile void * : 1, \
                              default : 0), \
                  "vnew: void pointer target, use valloc() with a size")
#define vnew(p, ...)
source
Expansion
#define vnew(p, ...) \
    ({ \
        VNEW_CHECK(p); \
        (VNEW_PTR(p)) valloc(sizeof(*(p)), ##__VA_ARGS__); \
    })
#define vnews(p, n, ...)
source
struct foo *arr = vnews(arr, count, ALLOC_ZERO);
Expansion
#define vnews(p, n, ...) \
    ({ \
        VNEW_CHECK(p); \
        size_t _vn_bytes_; \
        ci_mul_overflow((n), sizeof(*(p)), &_vn_bytes_) \
            ? (VNEW_PTR(p)) NULL \
            : (VNEW_PTR(p)) valloc(_vn_bytes_, ##__VA_ARGS__); \
    })
#define VNEW_FLEX_COUNTER(q, member)
source
Expansion
#define VNEW_FLEX_COUNTER(q, member) \
    _Generic(__builtin_counted_by_ref((q)->member), \
        void *: &(size_t) {0}, \
        default: __builtin_counted_by_ref((q)->member))
#define VNEW_FLEX_COUNTER(q, member)
source
Expansion
#define VNEW_FLEX_COUNTER(q, member) (&(size_t) {0})
#define vnew_flex(p, member, n, ...)
source

struct pkt { uint32_t len; uint8_t data[] cc_counted_by(len); };     struct pkt *pkt = vnew_flex(pkt, data, len, ALLOC_ZERO);

pkt->len = len when data is counted_by or NULL if len doesn’t fit it

Expansion
#define vnew_flex(p, member, n, ...) \
    ({ \
        VNEW_CHECK(p); \
        static_assert( \
            !__builtin_types_compatible_p(__typeof_unqual__((p)->member), \
                                          typeof(&(p)->member[0])), \
            "vnew_flex: member must be an array, not a pointer"); \
        size_t _vf_tail_, _vf_bytes_; \
        __typeof_unqual__(*VNEW_FLEX_COUNTER(p, member)) _vf_count_; \
        VNEW_PTR(p) _vf_q_ = NULL; \
        if (!ci_add_overflow((n), 0, &_vf_count_) && \
            !ci_mul_overflow((n), sizeof((p)->member[0]), &_vf_tail_) && \
            !ci_add_overflow(sizeof(*(p)), _vf_tail_, &_vf_bytes_)) { \
            _vf_q_ = (VNEW_PTR(p)) valloc(_vf_bytes_, ##__VA_ARGS__); \
            if (_vf_q_) \
                *VNEW_FLEX_COUNTER(_vf_q_, member) = _vf_count_; \
        } \
        _vf_q_; \
    })
#define vfree_aligned_1(ptr)
source
#define vfree_aligned_2(ptr, bh)
source
Expansion
#define vfree_aligned_2(ptr, bh) vfree_aligned_full((ptr), (bh))
#define vfree_aligned(...)
source
Expansion
#define vfree_aligned(...) PP_CALL(vfree_aligned, __VA_ARGS__)
#define vrealloc(ptr, size, ...)
source
Expansion
#define vrealloc(ptr, size, ...) \
    vrealloc_full((ptr), (size), \
                  alloc_params_with_defaults(ALLOC_FLAGS_DEFAULT, \
                                             ALLOC_BEHAVIOR_DEFAULT, \
                                             ##__VA_ARGS__))
#define vrenews(old, n, ...)
source
void **grown = vrenews(node->pages, needed);
Expansion
#define vrenews(old, n, ...) \
    ({ \
        VNEW_CHECK(old); \
        VNEW_PTR(old) _vr_old_ = (old); \
        size_t _vr_bytes_; \
        ci_mul_overflow((n), sizeof(*_vr_old_), &_vr_bytes_) \
            ? (VNEW_PTR(old)) NULL \
            : (VNEW_PTR(old)) vrealloc(_vr_old_, _vr_bytes_, ##__VA_ARGS__); \
    })