taisei/src/memory/mempool.h

72 lines
2 KiB
C

/*
* This software is licensed under the terms of the MIT License.
* See COPYING for further information.
* ---
* Copyright (c) 2011-2024, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2024, Andrei Alexeyev <akari@taisei-project.org>.
*/
#pragma once
#include "taisei.h"
#include "arena.h"
typedef struct MemPoolObjectHeader {
alignas(alignof(max_align_t)) struct MemPoolObjectHeader *next;
} MemPoolObjectHeader;
#define MEMPOOL_BASE(elem_type) struct { \
union { \
MemPoolObjectHeader *as_generic; \
elem_type *as_specific; \
} free_objects; \
uint num_allocated; \
uint num_used; \
} \
typedef MEMPOOL_BASE(max_align_t) MemPool;
#define MEMPOOL(elem_type) union { \
MEMPOOL_BASE(elem_type); \
MemPool as_generic; \
}
#define MEMPOOL_ASSERT_VALID(mpool) do { \
static_assert( \
__builtin_types_compatible_p(MemPool, __typeof__((mpool)->as_generic)), \
"x->as_generic must be of MemPool type"); \
static_assert( \
__builtin_offsetof(__typeof__(*(mpool)), as_generic) == 0, \
"x->as_generic must be the first member in struct"); \
} while(0)
#define MEMPOOL_CAST_TO_BASE(mpool) ({ \
MEMPOOL_ASSERT_VALID(mpool); \
&NOT_NULL(mpool)->as_generic; \
})
#define MEMPOOL_OBJTYPE(mpool) \
typeof(*(mpool)->free_objects.as_specific)
void *mempool_generic_acquire(MemPool *pool, MemArena *arena, size_t size, size_t align)
attr_returns_allocated attr_hot attr_nonnull(1, 2);
void mempool_generic_release(MemPool *pool, void *object)
attr_hot attr_nonnull(1, 2);
#define mempool_acquire(mpool, arena) ({ \
auto _mpool = mpool; \
MEMPOOL_OBJTYPE(_mpool) *_obj = mempool_generic_acquire(\
MEMPOOL_CAST_TO_BASE(_mpool), \
(arena), \
sizeof(MEMPOOL_OBJTYPE(_mpool)), \
alignof(MEMPOOL_OBJTYPE(_mpool))); \
*_obj = (typeof(*_obj)) {} ; \
_obj; \
})
#define mempool_release(mpool, obj) ({ \
static_assert( \
__builtin_types_compatible_p(typeof(*(obj)), MEMPOOL_OBJTYPE(mpool))); \
mempool_generic_release(MEMPOOL_CAST_TO_BASE(mpool), (obj)); \
})