1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "tb_mem.h" 35 36 /* 37 * Memory management routines for temporary memory. 38 * That memory is used only during build phase and is released after 39 * build is finished. 40 * Note, that tb_pool/tb_alloc() are not supposed to return NULL. 41 * Instead, in the case of failure to allocate memory, 42 * it would do siglongjmp(pool->fail). 43 * It is responsibility of the caller to save the proper context/environment, 44 * in the pool->fail before calling tb_alloc() for the given pool first time. 45 */ 46 47 static struct tb_mem_block * 48 tb_pool(struct tb_mem_pool *pool, size_t sz) 49 { 50 struct tb_mem_block *block; 51 uint8_t *ptr; 52 size_t size; 53 54 size = sz + pool->alignment - 1; 55 block = calloc(1, size + sizeof(*pool->block)); 56 if (block == NULL) { 57 RTE_LOG(ERR, MALLOC, "%s(%zu)\n failed, currently allocated " 58 "by pool: %zu bytes\n", __func__, sz, pool->alloc); 59 siglongjmp(pool->fail, -ENOMEM); 60 return NULL; 61 } 62 63 block->pool = pool; 64 65 block->next = pool->block; 66 pool->block = block; 67 68 pool->alloc += size; 69 70 ptr = (uint8_t *)(block + 1); 71 block->mem = RTE_PTR_ALIGN_CEIL(ptr, pool->alignment); 72 block->size = size - (block->mem - ptr); 73 74 return block; 75 } 76 77 void * 78 tb_alloc(struct tb_mem_pool *pool, size_t size) 79 { 80 struct tb_mem_block *block; 81 void *ptr; 82 size_t new_sz; 83 84 size = RTE_ALIGN_CEIL(size, pool->alignment); 85 86 block = pool->block; 87 if (block == NULL || block->size < size) { 88 new_sz = (size > pool->min_alloc) ? size : pool->min_alloc; 89 block = tb_pool(pool, new_sz); 90 } 91 ptr = block->mem; 92 block->size -= size; 93 block->mem += size; 94 return ptr; 95 } 96 97 void 98 tb_free_pool(struct tb_mem_pool *pool) 99 { 100 struct tb_mem_block *next, *block; 101 102 for (block = pool->block; block != NULL; block = next) { 103 next = block->next; 104 free(block); 105 } 106 pool->block = NULL; 107 pool->alloc = 0; 108 } 109