[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH v4 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 | 49 +++++++++++++++++++++ lib/ukallocpool/pool.c | 59 ++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/lib/ukallocpool/exportsyms.uk b/lib/ukallocpool/exportsyms.uk index 9d47d615..0bd38595 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_objlen uk_allocpool_take diff --git a/lib/ukallocpool/include/uk/allocpool.h b/lib/ukallocpool/include/uk/allocpool.h index 60a47482..7299286b 100644 --- a/lib/ukallocpool/include/uk/allocpool.h +++ b/lib/ukallocpool/include/uk/allocpool.h @@ -47,6 +47,55 @@ 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); + +/** + * 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 5d5ddbde..31fc8b2d 100644 --- a/lib/ukallocpool/pool.c +++ b/lib/ukallocpool/pool.c @@ -73,6 +73,9 @@ struct uk_allocpool { size_t obj_align; size_t obj_len; unsigned int obj_count; + + struct uk_alloc *parent; + void *base; }; struct free_obj { @@ -123,6 +126,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,49 @@ struct uk_allocpool *uk_allocpool_init(void *base, size_t len, out: p->obj_len = obj_alen; p->obj_align = obj_align; + 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) +{ + 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); + 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 |