19cc4651cSSandrine Bailleux /* 2*4c700c15SGovindraj Raja * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved. 39cc4651cSSandrine Bailleux * 49cc4651cSSandrine Bailleux * SPDX-License-Identifier: BSD-3-Clause 59cc4651cSSandrine Bailleux */ 69cc4651cSSandrine Bailleux 79cc4651cSSandrine Bailleux #ifndef OBJECT_POOL_H 89cc4651cSSandrine Bailleux #define OBJECT_POOL_H 99cc4651cSSandrine Bailleux 109cc4651cSSandrine Bailleux #include <stdlib.h> 1109d40e0eSAntonio Nino Diaz 1209d40e0eSAntonio Nino Diaz #include <common/debug.h> 1309d40e0eSAntonio Nino Diaz #include <lib/utils_def.h> 149cc4651cSSandrine Bailleux 159cc4651cSSandrine Bailleux /* 169cc4651cSSandrine Bailleux * Pool of statically allocated objects. 179cc4651cSSandrine Bailleux * 189cc4651cSSandrine Bailleux * Objects can be reserved but not freed. This is by design and it is not a 199cc4651cSSandrine Bailleux * limitation. We do not want to introduce complexity induced by memory freeing, 209cc4651cSSandrine Bailleux * such as use-after-free bugs, memory fragmentation and so on. 219cc4651cSSandrine Bailleux * 229cc4651cSSandrine Bailleux * The object size and capacity of the pool are fixed at build time. So is the 239cc4651cSSandrine Bailleux * address of the objects back store. 249cc4651cSSandrine Bailleux */ 259cc4651cSSandrine Bailleux struct object_pool { 269cc4651cSSandrine Bailleux /* Size of 1 object in the pool in byte unit. */ 279cc4651cSSandrine Bailleux const size_t obj_size; 289cc4651cSSandrine Bailleux 299cc4651cSSandrine Bailleux /* Number of objects in the pool. */ 309cc4651cSSandrine Bailleux const size_t capacity; 319cc4651cSSandrine Bailleux 329cc4651cSSandrine Bailleux /* Objects back store. */ 339cc4651cSSandrine Bailleux void *const objects; 349cc4651cSSandrine Bailleux 359cc4651cSSandrine Bailleux /* How many objects are currently allocated. */ 369cc4651cSSandrine Bailleux size_t used; 379cc4651cSSandrine Bailleux }; 389cc4651cSSandrine Bailleux 399cc4651cSSandrine Bailleux /* Create a static pool of objects. */ 409cc4651cSSandrine Bailleux #define OBJECT_POOL(_pool_name, _obj_backstore, _obj_size, _obj_count) \ 419cc4651cSSandrine Bailleux struct object_pool _pool_name = { \ 429cc4651cSSandrine Bailleux .objects = (_obj_backstore), \ 439cc4651cSSandrine Bailleux .obj_size = (_obj_size), \ 449cc4651cSSandrine Bailleux .capacity = (_obj_count), \ 459cc4651cSSandrine Bailleux .used = 0U, \ 469cc4651cSSandrine Bailleux } 479cc4651cSSandrine Bailleux 489cc4651cSSandrine Bailleux /* Create a static pool of objects out of an array of pre-allocated objects. */ 499cc4651cSSandrine Bailleux #define OBJECT_POOL_ARRAY(_pool_name, _obj_array) \ 509cc4651cSSandrine Bailleux OBJECT_POOL(_pool_name, (_obj_array), \ 519cc4651cSSandrine Bailleux sizeof((_obj_array)[0]), ARRAY_SIZE(_obj_array)) 529cc4651cSSandrine Bailleux 539cc4651cSSandrine Bailleux /* 549cc4651cSSandrine Bailleux * Allocate 'count' objects from a pool. 559cc4651cSSandrine Bailleux * Return the address of the first object. Panic on error. 569cc4651cSSandrine Bailleux */ 579cc4651cSSandrine Bailleux static inline void *pool_alloc_n(struct object_pool *pool, size_t count) 589cc4651cSSandrine Bailleux { 59845db722SLouis Mayencourt if ((pool->used + count) > pool->capacity) { 609cc4651cSSandrine Bailleux ERROR("Cannot allocate %zu objects out of pool (%zu objects left).\n", 619cc4651cSSandrine Bailleux count, pool->capacity - pool->used); 629cc4651cSSandrine Bailleux panic(); 639cc4651cSSandrine Bailleux } 649cc4651cSSandrine Bailleux 65845db722SLouis Mayencourt void *obj = (char *)(pool->objects) + (pool->obj_size * pool->used); 669cc4651cSSandrine Bailleux pool->used += count; 679cc4651cSSandrine Bailleux return obj; 689cc4651cSSandrine Bailleux } 699cc4651cSSandrine Bailleux 709cc4651cSSandrine Bailleux /* 719cc4651cSSandrine Bailleux * Allocate 1 object from a pool. 729cc4651cSSandrine Bailleux * Return the address of the object. Panic on error. 739cc4651cSSandrine Bailleux */ 749cc4651cSSandrine Bailleux static inline void *pool_alloc(struct object_pool *pool) 759cc4651cSSandrine Bailleux { 769cc4651cSSandrine Bailleux return pool_alloc_n(pool, 1U); 779cc4651cSSandrine Bailleux } 789cc4651cSSandrine Bailleux 799cc4651cSSandrine Bailleux #endif /* OBJECT_POOL_H */ 80