[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);
> +}



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.