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