1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include "tb_mem.h" 6 #include "acl_log.h" 7 8 /* 9 * Memory management routines for temporary memory. 10 * That memory is used only during build phase and is released after 11 * build is finished. 12 * Note, that tb_pool/tb_alloc() are not supposed to return NULL. 13 * Instead, in the case of failure to allocate memory, 14 * it would do siglongjmp(pool->fail). 15 * It is responsibility of the caller to save the proper context/environment, 16 * in the pool->fail before calling tb_alloc() for the given pool first time. 17 */ 18 19 static struct tb_mem_block * 20 tb_pool(struct tb_mem_pool *pool, size_t sz) 21 { 22 struct tb_mem_block *block; 23 uint8_t *ptr; 24 size_t size; 25 26 size = sz + pool->alignment - 1; 27 block = calloc(1, size + sizeof(*pool->block)); 28 if (block == NULL) { 29 ACL_LOG(ERR, "%s(%zu) failed, currently allocated by pool: %zu bytes", 30 __func__, sz, pool->alloc); 31 siglongjmp(pool->fail, -ENOMEM); 32 return NULL; 33 } 34 35 block->pool = pool; 36 37 block->next = pool->block; 38 pool->block = block; 39 40 pool->alloc += size; 41 42 ptr = (uint8_t *)(block + 1); 43 block->mem = RTE_PTR_ALIGN_CEIL(ptr, pool->alignment); 44 block->size = size - (block->mem - ptr); 45 46 return block; 47 } 48 49 void * 50 tb_alloc(struct tb_mem_pool *pool, size_t size) 51 { 52 struct tb_mem_block *block; 53 void *ptr; 54 size_t new_sz; 55 56 size = RTE_ALIGN_CEIL(size, pool->alignment); 57 58 block = pool->block; 59 if (block == NULL || block->size < size) { 60 new_sz = (size > pool->min_alloc) ? size : pool->min_alloc; 61 block = tb_pool(pool, new_sz); 62 } 63 ptr = block->mem; 64 block->size -= size; 65 block->mem += size; 66 return ptr; 67 } 68 69 void 70 tb_free_pool(struct tb_mem_pool *pool) 71 { 72 struct tb_mem_block *next, *block; 73 74 for (block = pool->block; block != NULL; block = next) { 75 next = block->next; 76 free(block); 77 } 78 pool->block = NULL; 79 pool->alloc = 0; 80 } 81