[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[UNIKRAFT PATCH 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 55d0ee56..d1dcf841 100644
--- a/lib/ukallocpool/pool.c
+++ b/lib/ukallocpool/pool.c
@@ -70,6 +70,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 {
@@ -122,6 +125,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,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



 


Rackspace

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