Skip to content

Commit 4933a08

Browse files
committed
Remove linear base alloc and use global base alloc everywhere
global base alloc free function now does not require size param
1 parent 36261a2 commit 4933a08

24 files changed

+165
-597
lines changed

src/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ set(UMF_LIBS umf_utils)
1515

1616
set(BA_SOURCES
1717
${CMAKE_CURRENT_SOURCE_DIR}/base_alloc/base_alloc.c
18-
${CMAKE_CURRENT_SOURCE_DIR}/base_alloc/base_alloc_linear.c
1918
${CMAKE_CURRENT_SOURCE_DIR}/base_alloc/base_alloc_global.c)
2019

2120
if (LINUX)

src/base_alloc/base_alloc_global.c

Lines changed: 84 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,114 @@ static int size_to_idx(size_t size) {
8283
return index;
8384
}
8485

85-
void *umf_ba_global_alloc(size_t size) {
86+
static void *transform_ptr(void *ptr, size_t size, size_t alignment) {
87+
assert(ptr);
88+
89+
void *user_ptr;
90+
if (alignment <= sizeof(size_t)) {
91+
user_ptr = (void *)((uintptr_t)ptr + sizeof(size_t));
92+
} else {
93+
user_ptr = (void *)ALIGN_UP((uintptr_t)ptr + sizeof(size_t), alignment);
94+
}
95+
96+
size_t ptr_offset_from_original = (uintptr_t)user_ptr - (uintptr_t)ptr;
97+
98+
size_t *metadata_loc = (size_t *)((char *)user_ptr - sizeof(size_t));
99+
*metadata_loc = size | (ptr_offset_from_original << 32);
100+
101+
return user_ptr;
102+
}
103+
104+
static void *get_original_alloc(void *user_ptr, size_t *total_size,
105+
size_t *usable_size) {
106+
assert(user_ptr);
107+
108+
size_t *metadata_loc = (size_t *)((char *)user_ptr - sizeof(size_t));
109+
110+
size_t stored_size = *metadata_loc & ((1ULL << 32) - 1);
111+
size_t ptr_offset_from_original = *metadata_loc >> 32;
112+
113+
void *original_ptr =
114+
(void *)((uintptr_t)user_ptr - ptr_offset_from_original);
115+
116+
if (total_size) {
117+
*total_size = stored_size;
118+
}
119+
120+
if (usable_size) {
121+
*usable_size = stored_size - ptr_offset_from_original;
122+
}
123+
124+
return original_ptr;
125+
}
126+
127+
void *umf_ba_global_aligned_alloc(size_t size, size_t alignment) {
86128
util_init_once(&ba_is_initialized, umf_ba_create_global);
87129

130+
// for metadata
131+
size += sizeof(size_t);
132+
133+
if (alignment > sizeof(size_t)) {
134+
size += alignment;
135+
}
136+
88137
if (size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) {
89138
#ifndef NDEBUG
90139
fprintf(stderr,
91140
"base_alloc: allocation size larger than the biggest "
92141
"allocation class. Falling back to OS memory allocation.\n");
93142
#endif
94-
return ba_os_alloc(size);
143+
return transform_ptr(ba_os_alloc(size), size, alignment);
95144
}
96145

97146
int ac_index = size_to_idx(size);
98147
if (!BASE_ALLOC.ac[ac_index]) {
99148
// if creating ac failed, fall back to os allocation
100149
fprintf(stderr, "base_alloc: allocation class not created. Falling "
101150
"back to OS memory allocation.\n");
102-
return ba_os_alloc(size);
151+
return transform_ptr(ba_os_alloc(size), size, alignment);
103152
}
104153

105-
return umf_ba_alloc(BASE_ALLOC.ac[ac_index]);
154+
return transform_ptr(umf_ba_alloc(BASE_ALLOC.ac[ac_index]), size,
155+
alignment);
106156
}
107157

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);
158+
void *umf_ba_global_alloc(size_t size) {
159+
return umf_ba_global_aligned_alloc(size, sizeof(size_t));
160+
}
161+
162+
void umf_ba_global_free(void *ptr) {
163+
if (!ptr) {
111164
return;
112165
}
113166

114-
int ac_index = size_to_idx(size);
167+
size_t total_size;
168+
ptr = get_original_alloc(ptr, &total_size, NULL);
169+
170+
if (total_size > BASE_ALLOC.ac_sizes[NUM_ALLOCATION_CLASSES - 1]) {
171+
ba_os_free(ptr, total_size);
172+
return;
173+
}
174+
175+
int ac_index = size_to_idx(total_size);
115176
if (!BASE_ALLOC.ac[ac_index]) {
116177
// if creating ac failed, memory must have been allocated by os
117-
ba_os_free(ptr, size);
178+
ba_os_free(ptr, total_size);
118179
return;
119180
}
120181

121182
umf_ba_free(BASE_ALLOC.ac[ac_index], ptr);
122183
}
184+
185+
size_t umf_ba_global_malloc_usable_size(void *ptr) {
186+
if (!ptr) {
187+
return 0;
188+
}
189+
190+
size_t usable_size;
191+
get_original_alloc(ptr, NULL, &usable_size);
192+
193+
assert(usable_size >= sizeof(size_t));
194+
195+
return usable_size;
196+
}

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
}

0 commit comments

Comments
 (0)