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" 6*73d85848SStephen 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 * 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*73d85848SStephen Hemminger RTE_LOG(ERR, ACL, "%s(%zu)\n failed, currently allocated " 3099a2dd95SBruce Richardson "by pool: %zu bytes\n", __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 * 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 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