|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH v3 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 | 51 +++++++++++++++++++++
lib/ukallocpool/pool.c | 62 ++++++++++++++++++++++++++
3 files changed, 116 insertions(+)
diff --git a/lib/ukallocpool/exportsyms.uk b/lib/ukallocpool/exportsyms.uk
index 2f29b409..9e19e8b2 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_take
uk_allocpool_return
diff --git a/lib/ukallocpool/include/uk/allocpool.h
b/lib/ukallocpool/include/uk/allocpool.h
index ce3d939d..13fbd187 100644
--- a/lib/ukallocpool/include/uk/allocpool.h
+++ b/lib/ukallocpool/include/uk/allocpool.h
@@ -47,6 +47,57 @@ 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,
+ uk_allocpool_obj_init_t obj_init,
+ void *obj_init_cookie);
+
+/**
+ * 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 d9614776..bbc50793 100644
--- a/lib/ukallocpool/pool.c
+++ b/lib/ukallocpool/pool.c
@@ -72,6 +72,9 @@ struct uk_allocpool {
unsigned int obj_count;
uk_allocpool_obj_init_t obj_init;
void *obj_init_cookie;
+
+ struct uk_alloc *parent;
+ void *base;
};
struct free_obj {
@@ -124,6 +127,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,52 @@ out:
p->obj_align = obj_align;
p->obj_init = obj_init;
p->obj_init_cookie = obj_init_cookie;
+ 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,
+ uk_allocpool_obj_init_t obj_init,
+ void *obj_init_cookie)
+{
+ 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,
+ obj_init, obj_init_cookie);
+ 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 |