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