[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH v2 3/5] lib/ukallocpool: Allocate pool on parent allocator
Provides a function that allocates and initializes a pool on a given parent allocator. Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> --- lib/ukallocpool/exportsyms.uk | 3 ++ lib/ukallocpool/include/uk/allocpool.h | 51 +++++++++++++++++++++ lib/ukallocpool/pool.c | 62 ++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/lib/ukallocpool/exportsyms.uk b/lib/ukallocpool/exportsyms.uk index 2f29b409..9e19e8b2 100644 --- a/lib/ukallocpool/exportsyms.uk +++ b/lib/ukallocpool/exportsyms.uk @@ -1,4 +1,7 @@ +uk_allocpool_alloc +uk_allocpool_free uk_allocpool_init +uk_allocpool_reqmem uk_allocpool_availcount uk_allocpool_take uk_allocpool_return diff --git a/lib/ukallocpool/include/uk/allocpool.h b/lib/ukallocpool/include/uk/allocpool.h index ce3d939d..13fbd187 100644 --- a/lib/ukallocpool/include/uk/allocpool.h +++ b/lib/ukallocpool/include/uk/allocpool.h @@ -47,6 +47,57 @@ typedef void (*uk_allocpool_obj_init_t)(void *obj, size_t len, void *cookie); struct uk_allocpool; +/** + * Computes the required memory for a pool allocation + * + * @param obj_count + * Number of objects that are allocated with the pool + * @param obj_len + * Size of one object (bytes) + * @param obj_align + * Alignment requirement for each pool object + * @return + * Number of bytes needed for pool allocation + */ +size_t uk_allocpool_reqmem(unsigned int obj_count, size_t obj_len, + size_t obj_align); + +/** + * Allocates a memory pool on a parent allocator. + * + * @param obj_count + * Number of objects that are allocated with the pool + * @param obj_len + * Size of one object (bytes) + * @param obj_align + * Alignment requirement for each pool object + * @param obj_init + * Function pointer to object initialization + * @param obj_init_cookie + * Cookie that is hand-over to object initialization + * @return + * - (NULL): If allocation failed (e.g., ENOMEM) + * - pointer to allocated pool + */ +struct uk_allocpool *uk_allocpool_alloc(struct uk_alloc *parent, + unsigned int obj_count, + size_t obj_len, size_t obj_align, + uk_allocpool_obj_init_t obj_init, + void *obj_init_cookie); + +/** + * Frees a memory pool that was allocated with + * uk_allocpool_alloc(). The memory is returned to + * the parent allocator. + * Note: Please make sure that all taken objects + * are returned to the pool before free'ing the + * pool. + * + * @param p + * Pointer to memory pool that will be free'd. + */ +void uk_allocpool_free(struct uk_allocpool *p); + /** * Initializes a memory pool on a given memory range. * diff --git a/lib/ukallocpool/pool.c b/lib/ukallocpool/pool.c index 2da97cef..a6d868b9 100644 --- a/lib/ukallocpool/pool.c +++ b/lib/ukallocpool/pool.c @@ -72,6 +72,9 @@ struct uk_allocpool { unsigned int obj_count; uk_allocpool_obj_init_t obj_init; void *obj_init_cookie; + + struct uk_alloc *parent; + void *base; }; struct free_obj { @@ -124,6 +127,21 @@ void uk_allocpool_return(struct uk_allocpool *p, void *obj) _prepend_free_obj(p, obj); } +size_t uk_allocpool_reqmem(unsigned int obj_count, size_t obj_len, + size_t obj_align) +{ + size_t obj_alen; + + UK_ASSERT(POWER_OF_2(obj_align)); + + obj_len = MAX(obj_len, MIN_OBJ_LEN); + obj_align = MAX(obj_align, MIN_OBJ_ALIGN); + obj_alen = ALIGN_UP(obj_len, obj_align); + return (sizeof(struct uk_allocpool) + + obj_align + + ((size_t) obj_count * obj_alen)); +} + unsigned int uk_allocpool_availcount(struct uk_allocpool *p) { return p->free_obj_count; @@ -181,8 +199,52 @@ out: p->obj_align = obj_align; p->obj_init = obj_init; p->obj_init_cookie = obj_init_cookie; + p->base = base; + p->parent = NULL; uk_pr_debug("%p: Pool created (%"__PRIsz" B): %u objs of %"__PRIsz" B, aligned to %"__PRIsz" B\n", p, len, p->obj_count, p->obj_len, p->obj_align); return p; } + +struct uk_allocpool *uk_allocpool_alloc(struct uk_alloc *parent, + unsigned int obj_count, + size_t obj_len, size_t obj_align, + uk_allocpool_obj_init_t obj_init, + void *obj_init_cookie) +{ + struct uk_allocpool *p; + void *base; + size_t len; + + /* uk_allocpool_reqmem computes minimum requirement */ + len = uk_allocpool_reqmem(obj_count, obj_len, obj_align); + base = uk_malloc(parent, len); + if (!base) + return NULL; + + p = uk_allocpool_init(base, len, obj_len, obj_align, + obj_init, obj_init_cookie); + if (!p) { + uk_free(parent, base); + errno = ENOSPC; + return NULL; + } + + p->parent = parent; + return p; +} + +void uk_allocpool_free(struct uk_allocpool *p) +{ + /* If we do not have a parent, this pool was created with + * uk_allocpool_init(). Such a pool cannot be free'd with + * this function since we are not the owner of the allocation + */ + UK_ASSERT(p->parent); + + /* Make sure we got all objects back */ + UK_ASSERT(p->free_obj_count == p->obj_count); + + uk_free(p->parent, p->base); +} -- 2.20.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |