|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [UNIKRAFT PATCH v5 3/5] lib/ukallocpool: Allocate pool on parent allocator
All good.
Reviewed-by: Razvan Deaconescu <razvan.deaconescu@xxxxxxxxx>
Simon Kuenzer <simon.kuenzer@xxxxxxxxx> writes:
> 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 | 47 ++++++++++++++++++++
> lib/ukallocpool/pool.c | 59 ++++++++++++++++++++++++++
> 3 files changed, 109 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 94f487de..c2ce31f0 100644
> --- a/lib/ukallocpool/include/uk/allocpool.h
> +++ b/lib/ukallocpool/include/uk/allocpool.h
> @@ -47,6 +47,53 @@ 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 parent
> + * Allocator on which the pool will be allocated.
> + * @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
> + * - (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 b6839b68..0b794d85 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;
> @@ -179,8 +197,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);
> +}
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |