summaryrefslogtreecommitdiffstats
path: root/include/lib/object_pool.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:13:47 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:13:47 +0000
commit102b0d2daa97dae68d3eed54d8fe37a9cc38a892 (patch)
treebcf648efac40ca6139842707f0eba5a4496a6dd2 /include/lib/object_pool.h
parentInitial commit. (diff)
downloadarm-trusted-firmware-upstream/2.8.0+dfsg.tar.xz
arm-trusted-firmware-upstream/2.8.0+dfsg.zip
Adding upstream version 2.8.0+dfsg.upstream/2.8.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--include/lib/object_pool.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/include/lib/object_pool.h b/include/lib/object_pool.h
new file mode 100644
index 0000000..66e8c47
--- /dev/null
+++ b/include/lib/object_pool.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef OBJECT_POOL_H
+#define OBJECT_POOL_H
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+#include <lib/utils_def.h>
+
+/*
+ * Pool of statically allocated objects.
+ *
+ * Objects can be reserved but not freed. This is by design and it is not a
+ * limitation. We do not want to introduce complexity induced by memory freeing,
+ * such as use-after-free bugs, memory fragmentation and so on.
+ *
+ * The object size and capacity of the pool are fixed at build time. So is the
+ * address of the objects back store.
+ */
+struct object_pool {
+ /* Size of 1 object in the pool in byte unit. */
+ const size_t obj_size;
+
+ /* Number of objects in the pool. */
+ const size_t capacity;
+
+ /* Objects back store. */
+ void *const objects;
+
+ /* How many objects are currently allocated. */
+ size_t used;
+};
+
+/* Create a static pool of objects. */
+#define OBJECT_POOL(_pool_name, _obj_backstore, _obj_size, _obj_count) \
+ struct object_pool _pool_name = { \
+ .objects = (_obj_backstore), \
+ .obj_size = (_obj_size), \
+ .capacity = (_obj_count), \
+ .used = 0U, \
+ }
+
+/* Create a static pool of objects out of an array of pre-allocated objects. */
+#define OBJECT_POOL_ARRAY(_pool_name, _obj_array) \
+ OBJECT_POOL(_pool_name, (_obj_array), \
+ sizeof((_obj_array)[0]), ARRAY_SIZE(_obj_array))
+
+/*
+ * Allocate 'count' objects from a pool.
+ * Return the address of the first object. Panic on error.
+ */
+static inline void *pool_alloc_n(struct object_pool *pool, size_t count)
+{
+ if ((pool->used + count) > pool->capacity) {
+ ERROR("Cannot allocate %zu objects out of pool (%zu objects left).\n",
+ count, pool->capacity - pool->used);
+ panic();
+ }
+
+ void *obj = (char *)(pool->objects) + (pool->obj_size * pool->used);
+ pool->used += count;
+ return obj;
+}
+
+/*
+ * Allocate 1 object from a pool.
+ * Return the address of the object. Panic on error.
+ */
+static inline void *pool_alloc(struct object_pool *pool)
+{
+ return pool_alloc_n(pool, 1U);
+}
+
+#endif /* OBJECT_POOL_H */