]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2010-2014 Intel Corporation | |
7c673cae FG |
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 | } |