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