[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 |