xref: /dpdk/lib/acl/tb_mem.c (revision ae67895b507bb6af22263c79ba0d5c374b396485)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #include "tb_mem.h"
673d85848SStephen Hemminger #include "acl_log.h"
799a2dd95SBruce Richardson 
899a2dd95SBruce Richardson /*
999a2dd95SBruce Richardson  *  Memory management routines for temporary memory.
1099a2dd95SBruce Richardson  *  That memory is used only during build phase and is released after
1199a2dd95SBruce Richardson  *  build is finished.
1299a2dd95SBruce Richardson  *  Note, that tb_pool/tb_alloc() are not supposed to return NULL.
1399a2dd95SBruce Richardson  *  Instead, in the case of failure to allocate memory,
1499a2dd95SBruce Richardson  *  it would do siglongjmp(pool->fail).
1599a2dd95SBruce Richardson  *  It is responsibility of the caller to save the proper context/environment,
1699a2dd95SBruce Richardson  *  in the pool->fail before calling tb_alloc() for the given pool first time.
1799a2dd95SBruce Richardson  */
1899a2dd95SBruce Richardson 
1999a2dd95SBruce Richardson static struct tb_mem_block *
tb_pool(struct tb_mem_pool * pool,size_t sz)2099a2dd95SBruce Richardson tb_pool(struct tb_mem_pool *pool, size_t sz)
2199a2dd95SBruce Richardson {
2299a2dd95SBruce Richardson 	struct tb_mem_block *block;
2399a2dd95SBruce Richardson 	uint8_t *ptr;
2499a2dd95SBruce Richardson 	size_t size;
2599a2dd95SBruce Richardson 
2699a2dd95SBruce Richardson 	size = sz + pool->alignment - 1;
2799a2dd95SBruce Richardson 	block = calloc(1, size + sizeof(*pool->block));
2899a2dd95SBruce Richardson 	if (block == NULL) {
29*ae67895bSDavid Marchand 		ACL_LOG(ERR, "%s(%zu) failed, currently allocated by pool: %zu bytes",
30f286e834SDavid Marchand 			__func__, sz, pool->alloc);
3199a2dd95SBruce Richardson 		siglongjmp(pool->fail, -ENOMEM);
3299a2dd95SBruce Richardson 		return NULL;
3399a2dd95SBruce Richardson 	}
3499a2dd95SBruce Richardson 
3599a2dd95SBruce Richardson 	block->pool = pool;
3699a2dd95SBruce Richardson 
3799a2dd95SBruce Richardson 	block->next = pool->block;
3899a2dd95SBruce Richardson 	pool->block = block;
3999a2dd95SBruce Richardson 
4099a2dd95SBruce Richardson 	pool->alloc += size;
4199a2dd95SBruce Richardson 
4299a2dd95SBruce Richardson 	ptr = (uint8_t *)(block + 1);
4399a2dd95SBruce Richardson 	block->mem = RTE_PTR_ALIGN_CEIL(ptr, pool->alignment);
4499a2dd95SBruce Richardson 	block->size = size - (block->mem - ptr);
4599a2dd95SBruce Richardson 
4699a2dd95SBruce Richardson 	return block;
4799a2dd95SBruce Richardson }
4899a2dd95SBruce Richardson 
4999a2dd95SBruce Richardson void *
tb_alloc(struct tb_mem_pool * pool,size_t size)5099a2dd95SBruce Richardson tb_alloc(struct tb_mem_pool *pool, size_t size)
5199a2dd95SBruce Richardson {
5299a2dd95SBruce Richardson 	struct tb_mem_block *block;
5399a2dd95SBruce Richardson 	void *ptr;
5499a2dd95SBruce Richardson 	size_t new_sz;
5599a2dd95SBruce Richardson 
5699a2dd95SBruce Richardson 	size = RTE_ALIGN_CEIL(size, pool->alignment);
5799a2dd95SBruce Richardson 
5899a2dd95SBruce Richardson 	block = pool->block;
5999a2dd95SBruce Richardson 	if (block == NULL || block->size < size) {
6099a2dd95SBruce Richardson 		new_sz = (size > pool->min_alloc) ? size : pool->min_alloc;
6199a2dd95SBruce Richardson 		block = tb_pool(pool, new_sz);
6299a2dd95SBruce Richardson 	}
6399a2dd95SBruce Richardson 	ptr = block->mem;
6499a2dd95SBruce Richardson 	block->size -= size;
6599a2dd95SBruce Richardson 	block->mem += size;
6699a2dd95SBruce Richardson 	return ptr;
6799a2dd95SBruce Richardson }
6899a2dd95SBruce Richardson 
6999a2dd95SBruce Richardson void
tb_free_pool(struct tb_mem_pool * pool)7099a2dd95SBruce Richardson tb_free_pool(struct tb_mem_pool *pool)
7199a2dd95SBruce Richardson {
7299a2dd95SBruce Richardson 	struct tb_mem_block *next, *block;
7399a2dd95SBruce Richardson 
7499a2dd95SBruce Richardson 	for (block = pool->block; block != NULL; block = next) {
7599a2dd95SBruce Richardson 		next = block->next;
7699a2dd95SBruce Richardson 		free(block);
7799a2dd95SBruce Richardson 	}
7899a2dd95SBruce Richardson 	pool->block = NULL;
7999a2dd95SBruce Richardson 	pool->alloc = 0;
8099a2dd95SBruce Richardson }
81