7d40b41d816a2d76fa72295744e19557603dc7d8
[project/bcm63xx/atf.git] / include / lib / object_pool.h
1 /*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef OBJECT_POOL_H
8 #define OBJECT_POOL_H
9
10 #include <debug.h>
11 #include <stdlib.h>
12 #include <utils_def.h>
13
14 /*
15 * Pool of statically allocated objects.
16 *
17 * Objects can be reserved but not freed. This is by design and it is not a
18 * limitation. We do not want to introduce complexity induced by memory freeing,
19 * such as use-after-free bugs, memory fragmentation and so on.
20 *
21 * The object size and capacity of the pool are fixed at build time. So is the
22 * address of the objects back store.
23 */
24 struct object_pool {
25 /* Size of 1 object in the pool in byte unit. */
26 const size_t obj_size;
27
28 /* Number of objects in the pool. */
29 const size_t capacity;
30
31 /* Objects back store. */
32 void *const objects;
33
34 /* How many objects are currently allocated. */
35 size_t used;
36 };
37
38 /* Create a static pool of objects. */
39 #define OBJECT_POOL(_pool_name, _obj_backstore, _obj_size, _obj_count) \
40 struct object_pool _pool_name = { \
41 .objects = (_obj_backstore), \
42 .obj_size = (_obj_size), \
43 .capacity = (_obj_count), \
44 .used = 0U, \
45 }
46
47 /* Create a static pool of objects out of an array of pre-allocated objects. */
48 #define OBJECT_POOL_ARRAY(_pool_name, _obj_array) \
49 OBJECT_POOL(_pool_name, (_obj_array), \
50 sizeof((_obj_array)[0]), ARRAY_SIZE(_obj_array))
51
52 /*
53 * Allocate 'count' objects from a pool.
54 * Return the address of the first object. Panic on error.
55 */
56 static inline void *pool_alloc_n(struct object_pool *pool, size_t count)
57 {
58 if (pool->used + count > pool->capacity) {
59 ERROR("Cannot allocate %zu objects out of pool (%zu objects left).\n",
60 count, pool->capacity - pool->used);
61 panic();
62 }
63
64 void *obj = (char *)(pool->objects) + pool->obj_size * pool->used;
65 pool->used += count;
66 return obj;
67 }
68
69 /*
70 * Allocate 1 object from a pool.
71 * Return the address of the object. Panic on error.
72 */
73 static inline void *pool_alloc(struct object_pool *pool)
74 {
75 return pool_alloc_n(pool, 1U);
76 }
77
78 #endif /* OBJECT_POOL_H */