mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:37:35 +00:00
malloc: Make it possible to recycle big allocation blocks as well.
This patch makes us recycle up to 8 blocks of 4KB size. This should probably be extended to handle other sizes.
This commit is contained in:
parent
1e0f9d325c
commit
5f7bb9d072
1 changed files with 29 additions and 2 deletions
|
@ -1,5 +1,6 @@
|
||||||
#include <AK/Bitmap.h>
|
#include <AK/Bitmap.h>
|
||||||
#include <AK/InlineLinkedList.h>
|
#include <AK/InlineLinkedList.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
#define PAGE_ROUND_UP(x) ((((size_t)(x)) + PAGE_SIZE-1) & (~(PAGE_SIZE-1)))
|
#define PAGE_ROUND_UP(x) ((((size_t)(x)) + PAGE_SIZE-1) & (~(PAGE_SIZE-1)))
|
||||||
|
|
||||||
static const size_t number_of_chunked_blocks_to_keep_around_per_size_class = 32;
|
static const size_t number_of_chunked_blocks_to_keep_around_per_size_class = 32;
|
||||||
|
static const size_t number_of_big_blocks_to_keep_around_per_size_class = 8;
|
||||||
|
|
||||||
static bool s_log_malloc = false;
|
static bool s_log_malloc = false;
|
||||||
static bool s_scrub_malloc = true;
|
static bool s_scrub_malloc = true;
|
||||||
|
@ -82,7 +84,12 @@ struct Allocator {
|
||||||
InlineLinkedList<ChunkedBlock> full_blocks;
|
InlineLinkedList<ChunkedBlock> full_blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BigAllocator {
|
||||||
|
Vector<BigAllocationBlock*> blocks;
|
||||||
|
};
|
||||||
|
|
||||||
static Allocator g_allocators[num_size_classes];
|
static Allocator g_allocators[num_size_classes];
|
||||||
|
static BigAllocator g_big_allocators[1];
|
||||||
|
|
||||||
static Allocator* allocator_for_size(size_t size, size_t& good_size)
|
static Allocator* allocator_for_size(size_t size, size_t& good_size)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +103,14 @@ static Allocator* allocator_for_size(size_t size, size_t& good_size)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BigAllocator* big_allocator_for_size(size_t size)
|
||||||
|
{
|
||||||
|
if (size == 4096)
|
||||||
|
return &g_big_allocators[0];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
size_t malloc_good_size(size_t size)
|
size_t malloc_good_size(size_t size)
|
||||||
|
@ -130,10 +145,16 @@ void* malloc(size_t size)
|
||||||
auto* allocator = allocator_for_size(size, good_size);
|
auto* allocator = allocator_for_size(size, good_size);
|
||||||
|
|
||||||
if (!allocator) {
|
if (!allocator) {
|
||||||
size_t real_size = sizeof(BigAllocationBlock) + size;
|
size_t real_size = PAGE_ROUND_UP(sizeof(BigAllocationBlock) + size);
|
||||||
|
if (auto* allocator = big_allocator_for_size(real_size)) {
|
||||||
|
if (!allocator->blocks.is_empty()) {
|
||||||
|
auto* block = allocator->blocks.take_last();
|
||||||
|
return &block->m_slot[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
auto* block = (BigAllocationBlock*)os_alloc(real_size);
|
auto* block = (BigAllocationBlock*)os_alloc(real_size);
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
snprintf(buffer, sizeof(buffer), "malloc: BigAllocationBlock(%u)", good_size);
|
snprintf(buffer, sizeof(buffer), "malloc: BigAllocationBlock(%u)", real_size);
|
||||||
set_mmap_name(block, PAGE_SIZE, buffer);
|
set_mmap_name(block, PAGE_SIZE, buffer);
|
||||||
new (block) BigAllocationBlock(real_size);
|
new (block) BigAllocationBlock(real_size);
|
||||||
return &block->m_slot[0];
|
return &block->m_slot[0];
|
||||||
|
@ -184,6 +205,12 @@ void free(void* ptr)
|
||||||
|
|
||||||
if (magic == MAGIC_BIGALLOC_HEADER) {
|
if (magic == MAGIC_BIGALLOC_HEADER) {
|
||||||
auto* block = (BigAllocationBlock*)page_base;
|
auto* block = (BigAllocationBlock*)page_base;
|
||||||
|
if (auto* allocator = big_allocator_for_size(block->m_size)) {
|
||||||
|
if (allocator->blocks.size() < number_of_big_blocks_to_keep_around_per_size_class) {
|
||||||
|
allocator->blocks.append(block);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
os_free(block, block->m_size);
|
os_free(block, block->m_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue