fix overly naive slab allocation alignment support
This commit is contained in:
parent
9a1acce5eb
commit
61684925e8
16
malloc.c
16
malloc.c
@ -47,6 +47,7 @@ struct slab_metadata {
|
|||||||
uint64_t canary_value;
|
uint64_t canary_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const size_t min_align = 16;
|
||||||
static const size_t max_slab_size_class = 16384;
|
static const size_t max_slab_size_class = 16384;
|
||||||
|
|
||||||
static const uint16_t size_classes[] = {
|
static const uint16_t size_classes[] = {
|
||||||
@ -93,6 +94,17 @@ static inline struct size_info get_size_info(size_t size) {
|
|||||||
fatal_error("invalid size for slabs");
|
fatal_error("invalid size for slabs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// alignment must be a power of 2 <= PAGE_SIZE since slabs are only page aligned
|
||||||
|
static inline struct size_info get_size_info_align(size_t size, size_t alignment) {
|
||||||
|
for (unsigned class = 1; class < N_SIZE_CLASSES; class++) {
|
||||||
|
size_t real_size = size_classes[class];
|
||||||
|
if (size <= real_size && !(real_size & (alignment - 1))) {
|
||||||
|
return (struct size_info){real_size, class};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fatal_error("invalid size for slabs");
|
||||||
|
}
|
||||||
|
|
||||||
static size_t get_slab_size(size_t slots, size_t size) {
|
static size_t get_slab_size(size_t slots, size_t size) {
|
||||||
return PAGE_CEILING(slots * size);
|
return PAGE_CEILING(slots * size);
|
||||||
}
|
}
|
||||||
@ -892,8 +904,8 @@ static int alloc_aligned(void **memptr, size_t alignment, size_t size, size_t mi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (alignment <= PAGE_SIZE) {
|
if (alignment <= PAGE_SIZE) {
|
||||||
if (size < alignment) {
|
if (size <= max_slab_size_class && alignment > min_align) {
|
||||||
size = alignment;
|
size = get_size_info_align(size, alignment).size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *p = allocate(size);
|
void *p = allocate(size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user