Skip to content

Commit c5ac00d

Browse files
committed
Global base alloc free function now does not require size param
Also, implement malloc_usable_size and aligned_alloc for global base alloc.
1 parent e9070a8 commit c5ac00d

16 files changed

+129
-60
lines changed

src/base_alloc/base_alloc_global.c

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@
1414
#include "base_alloc.h"
1515
#include "base_alloc_global.h"
1616
#include "base_alloc_internal.h"
17+
#include "utils_common.h"
1718
#include "utils_concurrency.h"
1819
#include "utils_math.h"
1920

2021
// global base allocator used by all providers and pools
2122
static UTIL_ONCE_FLAG ba_is_initialized = UTIL_ONCE_FLAG_INIT;
2223

23-
// allocation classes need to be powers of 2
24+
#define ALLOC_METADATA_SIZE (sizeof(size_t))
25+
26+
// allocation classes need to be consecutive powers of 2
2427
#define ALLOCATION_CLASSES \
2528
{ 16, 32, 64, 128 }
2629
#define NUM_ALLOCATION_CLASSES 4
@@ -82,41 +85,123 @@ static int size_to_idx(size_t size) {
8285
return index;
8386
}
8487

85-
void *umf_ba_global_alloc(size_t size) {
88+
// stores metadata just before 'ptr' and returns beginning of usable
89+
// space to the user. metadata consists of 'size' that is the allocation
90+
// size and 'offset' that specifies how far is the returned ptr from
91+
// the origin ptr (used for aligned alloc)
92+
static void *add_metadata_and_align(void *ptr, size_t size, size_t alignment) {
93+
assert(size < (1ULL << 32));
94+
assert(alignment < (1ULL << 32));
95+
assert(ptr);
96+
97+
void *user_ptr;
98+
if (alignment <= ALLOC_METADATA_SIZE) {
99+
user_ptr = (void *)((uintptr_t)ptr + ALLOC_METADATA_SIZE);
100+
} else {
101+
user_ptr =
102+
(void *)ALIGN_UP((uintptr_t)ptr + ALLOC_METADATA_SIZE, alignment);
103+
}
104+
105+
size_t ptr_offset_from_original = (uintptr_t)user_ptr - (uintptr_t)ptr;
106+
assert(ptr_offset_from_original < (1ULL << 32));
107+
108+
size_t *metadata_loc = (size_t *)((char *)user_ptr - ALLOC_METADATA_SIZE);
109+
*metadata_loc = size | (ptr_offset_from_original << 32);
110+
111+
return user_ptr;
112+
}
113+
114+
// return original ptr (the one that has been passed to add_metadata_and_align)
115+
// along with total allocation size (needed to find proper alloc class
116+
// in free) and usable size
117+
static void *get_original_alloc(void *user_ptr, size_t *total_size,
118+
size_t *usable_size) {
119+
assert(user_ptr);
120+
121+
size_t *metadata_loc = (size_t *)((char *)user_ptr - ALLOC_METADATA_SIZE);
122+
123+
size_t stored_size = *metadata_loc & ((1ULL << 32) - 1);
124+
size_t ptr_offset_from_original = *metadata_loc >> 32;
125+
126+
void *original_ptr =
127+
(void *)((uintptr_t)user_ptr - ptr_offset_from_original);
128+
129+
if (total_size) {
130+
*total_size = stored_size;
131+
}
132+
133+
if (usable_size) {
134+
*usable_size = stored_size - ptr_offset_from_original;
135+
}
136+
137+
return original_ptr;
138+
}
139+
140+
void *umf_ba_global_aligned_alloc(size_t size, size_t alignment) {
86141
util_init_once(&ba_is_initialized, umf_ba_create_global);
87142

143+
// for metadata
144+
size += ALLOC_METADATA_SIZE;
145+
146+
if (alignment > ALLOC_METADATA_SIZE) {
147+
size += alignment;
148+
}
149+
88150
if (size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) {
89151
#ifndef NDEBUG
90152
fprintf(stderr,
91153
"base_alloc: allocation size larger than the biggest "
92154
"allocation class. Falling back to OS memory allocation.\n");
93155
#endif
94-
return ba_os_alloc(size);
156+
return add_metadata_and_align(ba_os_alloc(size), size, alignment);
95157
}
96158

97159
int ac_index = size_to_idx(size);
98160
if (!BASE_ALLOC.ac[ac_index]) {
99161
// if creating ac failed, fall back to os allocation
100162
fprintf(stderr, "base_alloc: allocation class not created. Falling "
101163
"back to OS memory allocation.\n");
102-
return ba_os_alloc(size);
164+
return add_metadata_and_align(ba_os_alloc(size), size, alignment);
103165
}
104166

105-
return umf_ba_alloc(BASE_ALLOC.ac[ac_index]);
167+
return add_metadata_and_align(umf_ba_alloc(BASE_ALLOC.ac[ac_index]), size,
168+
alignment);
106169
}
107170

108-
void umf_ba_global_free(void *ptr, size_t size) {
109-
if (size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) {
110-
ba_os_free(ptr, size);
171+
void *umf_ba_global_alloc(size_t size) {
172+
return umf_ba_global_aligned_alloc(size, ALLOC_METADATA_SIZE);
173+
}
174+
175+
void umf_ba_global_free(void *ptr) {
176+
if (!ptr) {
111177
return;
112178
}
113179

114-
int ac_index = size_to_idx(size);
180+
size_t total_size;
181+
ptr = get_original_alloc(ptr, &total_size, NULL);
182+
183+
if (total_size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) {
184+
ba_os_free(ptr, total_size);
185+
return;
186+
}
187+
188+
int ac_index = size_to_idx(total_size);
115189
if (!BASE_ALLOC.ac[ac_index]) {
116190
// if creating ac failed, memory must have been allocated by os
117-
ba_os_free(ptr, size);
191+
ba_os_free(ptr, total_size);
118192
return;
119193
}
120194

121195
umf_ba_free(BASE_ALLOC.ac[ac_index], ptr);
122196
}
197+
198+
size_t umf_ba_global_malloc_usable_size(void *ptr) {
199+
if (!ptr) {
200+
return 0;
201+
}
202+
203+
size_t usable_size;
204+
get_original_alloc(ptr, NULL, &usable_size);
205+
206+
return usable_size;
207+
}

src/base_alloc/base_alloc_global.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ extern "C" {
1515
#endif
1616

1717
void *umf_ba_global_alloc(size_t size);
18-
void umf_ba_global_free(void *ptr, size_t size);
18+
void umf_ba_global_free(void *ptr);
1919
void umf_ba_destroy_global(void);
20+
size_t umf_ba_global_malloc_usable_size(void *ptr);
21+
void *umf_ba_global_aligned_alloc(size_t size, size_t alignment);
2022

2123
#ifdef __cplusplus
2224
}

src/critnib/critnib.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ struct critnib *critnib_new(void) {
211211
err_util_mutex_destroy:
212212
util_mutex_destroy_not_free(&c->mutex);
213213
err_free_critnib:
214-
umf_ba_global_free(c, sizeof(struct critnib));
214+
umf_ba_global_free(c);
215215
return NULL;
216216
}
217217

@@ -261,7 +261,7 @@ void critnib_delete(struct critnib *c) {
261261

262262
umf_ba_destroy(c->pool_nodes);
263263
umf_ba_destroy(c->pool_leaves);
264-
umf_ba_global_free(c, sizeof(struct critnib));
264+
umf_ba_global_free(c);
265265
}
266266

267267
/*

src/memory_pool_default.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
3939
pool->ops = *ops;
4040
ret = ops->initialize(pool->provider, params, &pool->pool_priv);
4141
if (ret != UMF_RESULT_SUCCESS) {
42-
umf_ba_global_free(pool, sizeof(umf_memory_pool_t));
42+
umf_ba_global_free(pool);
4343
return ret;
4444
}
4545

@@ -56,7 +56,7 @@ void umfPoolDestroy(umf_memory_pool_handle_t hPool) {
5656
umfMemoryProviderDestroy(hProvider);
5757
}
5858
// TODO: this free keeps memory in base allocator, so it can lead to OOM in some scenarios (it should be optimized)
59-
umf_ba_global_free(hPool, sizeof(umf_memory_pool_t));
59+
umf_ba_global_free(hPool);
6060
}
6161

6262
umf_result_t umfFree(void *ptr) {

src/memory_pool_tracking.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
5454
err_pool_init:
5555
umfMemoryProviderDestroy(pool->provider);
5656
err_provider_create:
57-
umf_ba_global_free(pool, sizeof(umf_memory_pool_t));
57+
umf_ba_global_free(pool);
5858
return ret;
5959
}
6060

@@ -69,7 +69,7 @@ void umfPoolDestroy(umf_memory_pool_handle_t hPool) {
6969
// Destroy tracking provider.
7070
umfMemoryProviderDestroy(hPool->provider);
7171
// TODO: this free keeps memory in base allocator, so it can lead to OOM in some scenarios (it should be optimized)
72-
umf_ba_global_free(hPool, sizeof(umf_memory_pool_t));
72+
umf_ba_global_free(hPool);
7373
}
7474

7575
umf_result_t umfFree(void *ptr) {

src/memory_provider.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops,
4545
void *provider_priv;
4646
umf_result_t ret = ops->initialize(params, &provider_priv);
4747
if (ret != UMF_RESULT_SUCCESS) {
48-
umf_ba_global_free(provider, sizeof(umf_memory_provider_t));
48+
umf_ba_global_free(provider);
4949
return ret;
5050
}
5151

@@ -58,7 +58,7 @@ umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops,
5858

5959
void umfMemoryProviderDestroy(umf_memory_provider_handle_t hProvider) {
6060
hProvider->ops.finalize(hProvider->provider_priv);
61-
umf_ba_global_free(hProvider, sizeof(umf_memory_provider_t));
61+
umf_ba_global_free(hProvider);
6262
}
6363

6464
static void

src/memory_target.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ umf_result_t umfMemoryTargetCreate(const umf_memory_target_ops_t *ops,
3737
void *target_priv;
3838
umf_result_t ret = ops->initialize(params, &target_priv);
3939
if (ret != UMF_RESULT_SUCCESS) {
40-
umf_ba_global_free(target, sizeof(umf_memory_target_t));
40+
umf_ba_global_free(target);
4141
return ret;
4242
}
4343

@@ -51,5 +51,5 @@ umf_result_t umfMemoryTargetCreate(const umf_memory_target_ops_t *ops,
5151
void umfMemoryTargetDestroy(umf_memory_target_handle_t memoryTarget) {
5252
assert(memoryTarget);
5353
memoryTarget->ops->finalize(memoryTarget->priv);
54-
umf_ba_global_free(memoryTarget, sizeof(umf_memory_target_t));
54+
umf_ba_global_free(memoryTarget);
5555
}

src/memory_targets/memory_target_numa.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ static umf_result_t numa_initialize(void *params, void **memTarget) {
4242
return UMF_RESULT_SUCCESS;
4343
}
4444

45-
static void numa_finalize(void *memTarget) {
46-
umf_ba_global_free(memTarget, sizeof(struct numa_memory_target_t));
47-
}
45+
static void numa_finalize(void *memTarget) { umf_ba_global_free(memTarget); }
4846

4947
// sets maxnode and allocates and initializes mask based on provided memory targets
5048
static umf_result_t
@@ -93,7 +91,7 @@ numa_targets_create_nodemask(struct numa_memory_target_t **targets,
9391
hwloc_bitmap_free(bitmap);
9492

9593
if (ret) {
96-
umf_ba_global_free(nodemask, *mask_size);
94+
umf_ba_global_free(nodemask);
9795
return UMF_RESULT_ERROR_UNKNOWN;
9896
}
9997

@@ -131,7 +129,7 @@ static enum umf_result_t numa_memory_provider_create_from_memspace(
131129
umf_memory_provider_handle_t numaProvider = NULL;
132130
ret = umfMemoryProviderCreate(umfOsMemoryProviderOps(), &params,
133131
&numaProvider);
134-
umf_ba_global_free(nodemask, nodemask_size);
132+
umf_ba_global_free(nodemask);
135133
if (ret) {
136134
return ret;
137135
}

src/memspace.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ umf_result_t umfPoolCreateFromMemspace(umf_memspace_handle_t memspace,
7070
ret = memspace->nodes[0]->ops->pool_create_from_memspace(
7171
memspace, privs, memspace->size, policy, pool);
7272

73-
umf_ba_global_free(privs, sizeof(void *) * memspace->size);
73+
umf_ba_global_free(privs);
7474

7575
return ret;
7676
}
@@ -95,7 +95,7 @@ umfMemoryProviderCreateFromMemspace(umf_memspace_handle_t memspace,
9595
ret = memspace->nodes[0]->ops->memory_provider_create_from_memspace(
9696
memspace, privs, memspace->size, policy, provider);
9797

98-
umf_ba_global_free(privs, sizeof(void *) * memspace->size);
98+
umf_ba_global_free(privs);
9999

100100
return ret;
101101
}
@@ -106,7 +106,6 @@ void umfMemspaceDestroy(umf_memspace_handle_t memspace) {
106106
umfMemoryTargetDestroy(memspace->nodes[i]);
107107
}
108108

109-
umf_ba_global_free(memspace->nodes,
110-
memspace->size * sizeof(umf_memory_target_handle_t));
111-
umf_ba_global_free(memspace, sizeof(struct umf_memspace_t));
109+
umf_ba_global_free(memspace->nodes);
110+
umf_ba_global_free(memspace);
112111
}

src/memspaces/memspace_host_all.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static umf_result_t umfMemspaceHostAllCreate(umf_memspace_handle_t *hMemspace) {
6262
umf_ret =
6363
umfMemspaceCreateFromNumaArray(nodeIds, (size_t)nNodes, hMemspace);
6464

65-
umf_ba_global_free(nodeIds, nNodes * sizeof(size_t));
65+
umf_ba_global_free(nodeIds);
6666

6767
err_topology_destroy:
6868
hwloc_topology_destroy(topology);

src/memspaces/memspace_numa.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,11 @@ umfMemspaceCreateFromNumaArray(size_t *nodeIds, size_t numIds,
5252
return UMF_RESULT_SUCCESS;
5353

5454
err_target_create:
55-
umf_ba_global_free(memspace->nodes,
56-
memspace->size * sizeof(umf_memory_target_handle_t));
55+
umf_ba_global_free(memspace->nodes);
5756
for (size_t i = 0; i < nodeIdx; i++) {
5857
umfMemoryTargetDestroy(memspace->nodes[i]);
5958
}
6059
err_nodes_alloc:
61-
umf_ba_global_free(memspace, sizeof(struct umf_memspace_t));
60+
umf_ba_global_free(memspace);
6261
return ret;
6362
}

src/pool/pool_jemalloc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ static umf_result_t je_initialize(umf_memory_provider_handle_t provider,
395395
return UMF_RESULT_SUCCESS;
396396

397397
err_free_pool:
398-
umf_ba_global_free(pool, sizeof(jemalloc_memory_pool_t));
398+
umf_ba_global_free(pool);
399399
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
400400
}
401401

@@ -406,7 +406,7 @@ static void je_finalize(void *pool) {
406406
snprintf(cmd, sizeof(cmd), "arena.%u.destroy", je_pool->arena_index);
407407
mallctl(cmd, NULL, 0, NULL, 0);
408408
pool_by_arena_index[je_pool->arena_index] = NULL;
409-
umf_ba_global_free(je_pool, sizeof(jemalloc_memory_pool_t));
409+
umf_ba_global_free(je_pool);
410410
}
411411

412412
static size_t je_malloc_usable_size(void *pool, void *ptr) {

src/pool/pool_scalable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ static void tbb_pool_finalize(void *pool) {
171171
util_init_once(&tbb_is_initialized, init_tbb_global_state);
172172
struct tbb_memory_pool *pool_data = (struct tbb_memory_pool *)pool;
173173
g_tbb_ops.pool_destroy(pool_data->tbb_pool);
174-
umf_ba_global_free(pool_data, sizeof(struct tbb_memory_pool));
174+
umf_ba_global_free(pool_data);
175175
}
176176

177177
static void *tbb_malloc(void *pool, size_t size) {

src/provider/provider_os_memory.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ static umf_result_t os_initialize(void *params, void **provider) {
278278
err_destroy_hwloc_topology:
279279
hwloc_topology_destroy(os_provider->topo);
280280
err_free_os_provider:
281-
umf_ba_global_free(os_provider, sizeof(os_memory_provider_t));
281+
umf_ba_global_free(os_provider);
282282
return ret;
283283
}
284284

@@ -291,7 +291,7 @@ static void os_finalize(void *provider) {
291291
os_memory_provider_t *os_provider = provider;
292292
hwloc_bitmap_free(os_provider->nodeset);
293293
hwloc_topology_destroy(os_provider->topo);
294-
umf_ba_global_free(os_provider, sizeof(os_memory_provider_t));
294+
umf_ba_global_free(os_provider);
295295
}
296296

297297
static umf_result_t os_get_min_page_size(void *provider, void *ptr,

0 commit comments

Comments
 (0)