|
5 | 5 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | 6 | */ |
7 | 7 |
|
8 | | -#include <assert.h> |
| 8 | +/* A MT-safe base allocator */ |
9 | 9 |
|
| 10 | +#include "base_alloc_global.h" |
10 | 11 | #include "base_alloc.h" |
| 12 | +#include "base_alloc_internal.h" |
| 13 | +#include "utils_math.h" |
11 | 14 |
|
12 | | -#define SIZE_BA_POOL_CHUNK 128 |
| 15 | +#include <stdio.h> |
13 | 16 |
|
14 | | -// global base allocator used by all providers and pools |
15 | | -static umf_ba_pool_t *BA_pool = NULL; |
| 17 | +// allocation classes need to be powers of 2 |
| 18 | +#define ALLOCATION_CLASSES \ |
| 19 | + { 16, 32, 64, 128 } |
| 20 | +#define NUM_ALLOCATION_CLASSES 4 |
16 | 21 |
|
17 | | -int umf_ba_create_global(void) { |
18 | | - assert(BA_pool == NULL); |
| 22 | +struct base_alloc_t { |
| 23 | + size_t ac_sizes[NUM_ALLOCATION_CLASSES]; |
| 24 | + umf_ba_pool_t *ac[NUM_ALLOCATION_CLASSES]; |
| 25 | + size_t smallest_ac_size_log2; |
| 26 | +}; |
19 | 27 |
|
20 | | - BA_pool = umf_ba_create(SIZE_BA_POOL_CHUNK); |
21 | | - if (!BA_pool) { |
22 | | - return -1; |
| 28 | +static struct base_alloc_t BASE_ALLOC = {.ac_sizes = ALLOCATION_CLASSES}; |
| 29 | + |
| 30 | +void umf_ba_create_global(void) { |
| 31 | + for (int i = 0; i < NUM_ALLOCATION_CLASSES; i++) { |
| 32 | + // allocation classes need to be powers of 2 |
| 33 | + assert(0 == (BASE_ALLOC.ac_sizes[i] & (BASE_ALLOC.ac_sizes[i] - 1))); |
| 34 | + BASE_ALLOC.ac[i] = umf_ba_create(BASE_ALLOC.ac_sizes[i]); |
| 35 | + if (!BASE_ALLOC.ac[i]) { |
| 36 | + fprintf(stderr, |
| 37 | + "Cannot create base alloc allocation class for size: %zu\n", |
| 38 | + BASE_ALLOC.ac_sizes[i]); |
| 39 | + } |
23 | 40 | } |
24 | 41 |
|
25 | | - return 0; |
| 42 | + size_t smallestSize = BASE_ALLOC.ac_sizes[0]; |
| 43 | + BASE_ALLOC.smallest_ac_size_log2 = log2Utils(smallestSize); |
26 | 44 | } |
27 | 45 |
|
28 | 46 | void umf_ba_destroy_global(void) { |
29 | | - assert(BA_pool); |
30 | | - umf_ba_destroy(BA_pool); |
31 | | - BA_pool = NULL; |
| 47 | + for (int i = 0; i < NUM_ALLOCATION_CLASSES; i++) { |
| 48 | + if (BASE_ALLOC.ac[i]) { |
| 49 | + umf_ba_destroy(BASE_ALLOC.ac[i]); |
| 50 | + } |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +// returns index of the allocation class for a give size |
| 55 | +static int size_to_idx(size_t size) { |
| 56 | + assert(size <= BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]); |
| 57 | + |
| 58 | + if (size <= BASE_ALLOC.ac_sizes[0]) { |
| 59 | + return 0; |
| 60 | + } |
| 61 | + |
| 62 | + int isPowerOf2 = (0 == (size & (size - 1))); |
| 63 | + int index = |
| 64 | + (int)(log2Utils(size) + !isPowerOf2 - BASE_ALLOC.smallest_ac_size_log2); |
| 65 | + |
| 66 | + assert(index >= 0); |
| 67 | + assert(index < NUM_ALLOCATION_CLASSES); |
| 68 | + |
| 69 | + return index; |
| 70 | +} |
| 71 | + |
| 72 | +void *umf_ba_global_alloc(size_t size) { |
| 73 | + if (size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) { |
| 74 | + return ba_os_alloc(size); |
| 75 | + } |
| 76 | + |
| 77 | + int ac_index = size_to_idx(size); |
| 78 | + if (!BASE_ALLOC.ac[ac_index]) { |
| 79 | + // if creating ac failed, fall back to os allocation |
| 80 | + return ba_os_alloc(size); |
| 81 | + } |
| 82 | + |
| 83 | + return umf_ba_alloc(BASE_ALLOC.ac[ac_index]); |
32 | 84 | } |
33 | 85 |
|
34 | | -umf_ba_pool_t *umf_ba_get_pool(size_t size) { |
35 | | - // TODO: a specific class-size base allocator can be returned here |
36 | | - assert(BA_pool); |
37 | | - assert(size <= SIZE_BA_POOL_CHUNK); |
| 86 | +void umf_ba_global_free(void *ptr, size_t size) { |
| 87 | + if (size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) { |
| 88 | + ba_os_free(ptr, size); |
| 89 | + return; |
| 90 | + } |
38 | 91 |
|
39 | | - if (size > SIZE_BA_POOL_CHUNK) { |
40 | | - return NULL; |
| 92 | + int ac_index = size_to_idx(size); |
| 93 | + if (!BASE_ALLOC.ac[ac_index]) { |
| 94 | + // if creating ac failed, memory must have been allocated by os |
| 95 | + ba_os_free(ptr, size); |
| 96 | + return; |
41 | 97 | } |
42 | 98 |
|
43 | | - return BA_pool; |
| 99 | + umf_ba_free(BASE_ALLOC.ac[ac_index], ptr); |
44 | 100 | } |
0 commit comments