Skip to content

Commit 60ac276

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 60ac276

16 files changed

+125
-60
lines changed

src/base_alloc/base_alloc_global.c

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
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+
// allocation classes need to be consecutive powers of 2
2425
#define ALLOCATION_CLASSES \
2526
{ 16, 32, 64, 128 }
2627
#define NUM_ALLOCATION_CLASSES 4
@@ -82,41 +83,121 @@ static int size_to_idx(size_t size) {
8283
return index;
8384
}
8485

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

139+
// for metadata
140+
size += sizeof(size_t);
141+
142+
if (alignment > sizeof(size_t)) {
143+
size += alignment;
144+
}
145+
88146
if (size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) {
89147
#ifndef NDEBUG
90148
fprintf(stderr,
91149
"base_alloc: allocation size larger than the biggest "
92150
"allocation class. Falling back to OS memory allocation.\n");
93151
#endif
94-
return ba_os_alloc(size);
152+
return transform_ptr(ba_os_alloc(size), size, alignment);
95153
}
96154

97155
int ac_index = size_to_idx(size);
98156
if (!BASE_ALLOC.ac[ac_index]) {
99157
// if creating ac failed, fall back to os allocation
100158
fprintf(stderr, "base_alloc: allocation class not created. Falling "
101159
"back to OS memory allocation.\n");
102-
return ba_os_alloc(size);
160+
return transform_ptr(ba_os_alloc(size), size, alignment);
103161
}
104162

105-
return umf_ba_alloc(BASE_ALLOC.ac[ac_index]);
163+
return transform_ptr(umf_ba_alloc(BASE_ALLOC.ac[ac_index]), size,
164+
alignment);
106165
}
107166

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);
167+
void *umf_ba_global_alloc(size_t size) {
168+
return umf_ba_global_aligned_alloc(size, sizeof(size_t));
169+
}
170+
171+
void umf_ba_global_free(void *ptr) {
172+
if (!ptr) {
111173
return;
112174
}
113175

114-
int ac_index = size_to_idx(size);
176+
size_t total_size;
177+
ptr = get_original_alloc(ptr, &total_size, NULL);
178+
179+
if (total_size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) {
180+
ba_os_free(ptr, total_size);
181+
return;
182+
}
183+
184+
int ac_index = size_to_idx(total_size);
115185
if (!BASE_ALLOC.ac[ac_index]) {
116186
// if creating ac failed, memory must have been allocated by os
117-
ba_os_free(ptr, size);
187+
ba_os_free(ptr, total_size);
118188
return;
119189
}
120190

121191
umf_ba_free(BASE_ALLOC.ac[ac_index], ptr);
122192
}
193+
194+
size_t umf_ba_global_malloc_usable_size(void *ptr) {
195+
if (!ptr) {
196+
return 0;
197+
}
198+
199+
size_t usable_size;
200+
get_original_alloc(ptr, NULL, &usable_size);
201+
202+
return usable_size;
203+
}

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,

src/provider/provider_tracking.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ static void trackingFinalize(void *provider) {
386386
check_if_tracker_is_empty(p->hTracker, p->pool);
387387
#endif /* NDEBUG */
388388

389-
umf_ba_global_free(provider, sizeof(umf_tracking_memory_provider_t));
389+
umf_ba_global_free(provider);
390390
}
391391

392392
static void trackingGetLastError(void *provider, const char **msg,
@@ -502,7 +502,7 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) {
502502
err_destroy_tracker_allocator:
503503
umf_ba_destroy(tracker_allocator);
504504
err_free_handle:
505-
umf_ba_global_free(handle, sizeof(struct umf_memory_tracker_t));
505+
umf_ba_global_free(handle);
506506
return NULL;
507507
}
508508

@@ -530,5 +530,5 @@ void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) {
530530
util_mutex_destroy_not_free(&handle->splitMergeMutex);
531531
umf_ba_destroy(handle->tracker_allocator);
532532
handle->tracker_allocator = NULL;
533-
umf_ba_global_free(handle, sizeof(struct umf_memory_tracker_t));
533+
umf_ba_global_free(handle);
534534
}

0 commit comments

Comments
 (0)