"bl2/git@web.lueluesay.top:root/arm-trusted-firmware.git" did not exist on "a759d34519d4206dfe0a86389317c4b371850aa7"
  • Sandrine Bailleux's avatar
    Introduce object pool allocator · 9cc4651c
    Sandrine Bailleux authored
    
    The object pool allocator provides a simplistic interface to manage
    allocation in a fixed-size static array. The caller creates a static
    "object pool" out of such an array and may then call pool_alloc() to
    get the next available object within the pool. There is also a variant
    to get multiple consecutive objects: pool_alloc_n().
    
    Note that this interface does not provide any way to free the objects
    afterwards. 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.
    
    Change-Id: Iefc2e153767851fbde5841a295f92ae48adda71f
    Signed-off-by: default avatarSandrine Bailleux <sandrine.bailleux@arm.com>
    9cc4651c
object_pool.h 2.04 KB
/*
 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef OBJECT_POOL_H
#define OBJECT_POOL_H

#include <debug.h>
#include <stdlib.h>
#include <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 */