|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [UNIKRAFT PATCH v5 4/5] lib/ukallocpool: `lib/ukalloc` compatible interface
All good.
Reviewed-by: Razvan Deaconescu <razvan.deaconescu@xxxxxxxxx>
Simon Kuenzer <simon.kuenzer@xxxxxxxxx> writes:
> Provide a ukalloc compatible interface. This enables the usage of pools
> with common allocator interfaces, like `uk_malloc()`, `uk_free()`,
> and `uk_memalign()`.
>
> Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> ---
> lib/ukallocpool/exportsyms.uk | 1 +
> lib/ukallocpool/include/uk/allocpool.h | 16 ++++++
> lib/ukallocpool/pool.c | 80 ++++++++++++++++++++++++++
> 3 files changed, 97 insertions(+)
>
> diff --git a/lib/ukallocpool/exportsyms.uk b/lib/ukallocpool/exportsyms.uk
> index 0bd38595..68c16ebe 100644
> --- a/lib/ukallocpool/exportsyms.uk
> +++ b/lib/ukallocpool/exportsyms.uk
> @@ -6,3 +6,4 @@ uk_allocpool_availcount
> uk_allocpool_objlen
> uk_allocpool_take
> uk_allocpool_return
> +uk_allocpool2ukalloc
> diff --git a/lib/ukallocpool/include/uk/allocpool.h
> b/lib/ukallocpool/include/uk/allocpool.h
> index c2ce31f0..1f6747f1 100644
> --- a/lib/ukallocpool/include/uk/allocpool.h
> +++ b/lib/ukallocpool/include/uk/allocpool.h
> @@ -112,6 +112,18 @@ void uk_allocpool_free(struct uk_allocpool *p);
> struct uk_allocpool *uk_allocpool_init(void *base, size_t len,
> size_t obj_len, size_t obj_align);
>
> +/**
> + * Return uk_alloc compatible interface for allocpool.
> + * With this interface, uk_malloc(), uk_free(), etc. can
> + * be used with the pool.
> + *
> + * @param p
> + * Pointer to memory pool.
> + * @return
> + * Pointer to uk_alloc interface of given pool.
> + */
> +struct uk_alloc *uk_allocpool2ukalloc(struct uk_allocpool *p);
> +
> /**
> * Return the number of current available (free) objects.
> *
> @@ -134,6 +146,8 @@ size_t uk_allocpool_objlen(struct uk_allocpool *p);
>
> /**
> * Get one object from a pool.
> + * HINT: It is recommended to use this call instead of uk_malloc() whenever
> + * feasible. This call is avoiding indirections.
> *
> * @param p
> * Pointer to memory pool.
> @@ -145,6 +159,8 @@ void *uk_allocpool_take(struct uk_allocpool *p);
>
> /**
> * Return one object back to a pool.
> + * HINT: It is recommended to use this call instead of uk_free() whenever
> + * feasible. This call is avoiding indirections.
> *
> * @param p
> * Pointer to memory pool.
> diff --git a/lib/ukallocpool/pool.c b/lib/ukallocpool/pool.c
> index 0b794d85..a7c3acf0 100644
> --- a/lib/ukallocpool/pool.c
> +++ b/lib/ukallocpool/pool.c
> @@ -67,6 +67,8 @@
> #define MIN_OBJ_LEN sizeof(struct uk_list_head)
>
> struct uk_allocpool {
> + struct uk_alloc self;
> +
> struct uk_list_head free_obj;
> unsigned int free_obj_count;
>
> @@ -82,6 +84,21 @@ struct free_obj {
> struct uk_list_head list;
> };
>
> +static inline struct uk_allocpool *ukalloc2pool(struct uk_alloc *a)
> +{
> + UK_ASSERT(a);
> + return __containerof(a, struct uk_allocpool, self);
> +}
> +
> +#define allocpool2ukalloc(p) \
> + (&(p)->self)
> +
> +struct uk_alloc *uk_allocpool2ukalloc(struct uk_allocpool *p)
> +{
> + UK_ASSERT(p);
> + return allocpool2ukalloc(p);
> +}
> +
> static inline void _prepend_free_obj(struct uk_allocpool *p, void *obj)
> {
> struct uk_list_head *entry;
> @@ -109,6 +126,42 @@ static inline void *_take_free_obj(struct uk_allocpool
> *p)
> return (void *) obj;
> }
>
> +static void pool_free(struct uk_alloc *a, void *ptr)
> +{
> + struct uk_allocpool *p = ukalloc2pool(a);
> +
> + if (likely(ptr))
> + _prepend_free_obj(p, ptr);
> +}
> +
> +static void *pool_malloc(struct uk_alloc *a, size_t size)
> +{
> + struct uk_allocpool *p = ukalloc2pool(a);
> +
> + if (unlikely((size > p->obj_len)
> + || uk_list_empty(&p->free_obj))) {
> + errno = ENOMEM;
> + return NULL;
> + }
> +
> + return _take_free_obj(p);
> +}
> +
> +static int pool_posix_memalign(struct uk_alloc *a, void **memptr, size_t
> align,
> + size_t size)
> +{
> + struct uk_allocpool *p = ukalloc2pool(a);
> +
> + if (unlikely((size > p->obj_len)
> + || (align > p->obj_align)
> + || uk_list_empty(&p->free_obj))) {
> + return ENOMEM;
> + }
> +
> + *memptr = _take_free_obj(p);
> + return 0;
> +}
> +
> void *uk_allocpool_take(struct uk_allocpool *p)
> {
> UK_ASSERT(p);
> @@ -126,6 +179,15 @@ void uk_allocpool_return(struct uk_allocpool *p, void
> *obj)
> _prepend_free_obj(p, obj);
> }
>
> +#if CONFIG_LIBUKALLOC_IFSTATS
> +static ssize_t pool_availmem(struct uk_alloc *a)
> +{
> + struct uk_allocpool *p = ukalloc2pool(a);
> +
> + return (size_t) p->free_obj_count * p->obj_len;
> +}
> +#endif
> +
> size_t uk_allocpool_reqmem(unsigned int obj_count, size_t obj_len,
> size_t obj_align)
> {
> @@ -155,6 +217,7 @@ struct uk_allocpool *uk_allocpool_init(void *base, size_t
> len,
> size_t obj_len, size_t obj_align)
> {
> struct uk_allocpool *p;
> + struct uk_alloc *a;
> size_t obj_alen;
> size_t left;
> void *obj_ptr;
> @@ -172,6 +235,7 @@ struct uk_allocpool *uk_allocpool_init(void *base, size_t
> len,
>
> p = (struct uk_allocpool *) base;
> memset(p, 0, sizeof(*p));
> + a = allocpool2ukalloc(p);
>
> obj_alen = ALIGN_UP(obj_len, obj_align);
> obj_ptr = (void *) ALIGN_UP((uintptr_t) base + sizeof(*p),
> @@ -200,6 +264,18 @@ out:
> p->base = base;
> p->parent = NULL;
>
> + uk_alloc_init_malloc(a,
> + pool_malloc,
> + uk_calloc_compat,
> + uk_realloc_compat,
> + pool_free,
> + pool_posix_memalign,
> + uk_memalign_compat,
> + NULL);
> +#if CONFIG_LIBUKALLOC_IFSTATS
> + p->self.availmem = pool_availmem;
> +#endif
> +
> 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;
> @@ -241,5 +317,9 @@ void uk_allocpool_free(struct uk_allocpool *p)
> /* Make sure we got all objects back */
> UK_ASSERT(p->free_obj_count == p->obj_count);
>
> + /* FIXME: Unregister `ukalloc` interface from `lib/ukalloc` */
> + /* TODO: Provide unregistration interface at `lib/ukalloc` */
> + UK_CRASH("Unregistering from `lib/ukalloc` not implemented.\n");
> +
> uk_free(p->parent, p->base);
> }
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |