| /* |
| * 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 */ |