object_pool.h 2.1 KB

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