优化内存管理模块中raw allocator的内存利用效率

This commit is contained in:
pointer-to-bios 2024-01-15 19:58:01 +08:00
parent 6f049d9ca2
commit af179fc127
3 changed files with 60 additions and 20 deletions

View File

@ -11,17 +11,25 @@ typedef struct __raw_allocator_cell
usize length; // 是实际使用的长度 usize length; // 是实际使用的长度
u8 content[0]; u8 content[0];
} raw_allocator_cell; } raw_allocator_cell;
#define raw_allocator_next_cell(cell) (raw_allocator_cell *)((void *)((cell)->content) + (cell)->capacity)
// 原始分配器 // 原始分配器
// 包括至少一个cell分配时像cell的分裂一样将空白的一段分成两段 //
// 释放时只把length归零并不将cell合并 // 包括至少一个cell分配时像cell的分裂一样将空白的一段分成两段
// 释放时只把length归零并不将cell合并。
// length=0的cell称为空cell // length=0的cell称为空cell
// 在分配时遇到第一个空cell时将紧随其后的空cell都合并掉 //
// 统计从上次细胞合并以来free的调用次数当调用次数很多或可用空间不足时
// 触发细胞合并。
typedef struct __raw_allocator_t typedef struct __raw_allocator_t
{ {
usize size, reserved; usize size;
usize free_count; // free调用计数
#define RAW_ALLOCATOR_FREE_MAX 64
usize rest_memory;
raw_allocator_cell cells[0]; raw_allocator_cell cells[0];
} raw_allocator_t; } raw_allocator_t;
#define raw_allocator_end(allocator) ((void *)(allocator) + (allocator)->size)
void raw_allocator_new(raw_allocator_t *allocator, usize size); void raw_allocator_new(raw_allocator_t *allocator, usize size);

View File

@ -43,7 +43,9 @@ void kmain(void *mb2_bootinfo)
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text); tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
tty_set_framebuffer(tty0, &fb); tty_set_framebuffer(tty0, &fb);
tty_text_print(tty0, "Hello Metaverse!\n", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0)); tty_text_print(tty0, "Hello ", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0));
tty_text_print(tty0, "Metaverse", gen_color(0x0a, 0xee, 0x0a), gen_color(0, 0, 0));
tty_text_print(tty0, "!\n", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0));
// 初始化内核日志模块 // 初始化内核日志模块

View File

@ -7,54 +7,84 @@
void raw_allocator_new(raw_allocator_t *allocator, usize size) void raw_allocator_new(raw_allocator_t *allocator, usize size)
{ {
allocator->size = size - sizeof(allocator->size); allocator->size = size - sizeof(allocator->size);
allocator->cells[0].capacity = size - sizeof(raw_allocator_t); allocator->free_count = 0;
allocator->rest_memory = size - sizeof(raw_allocator_t);
allocator->cells[0].capacity = size - sizeof(raw_allocator_t) - sizeof(raw_allocator_cell);
allocator->cells[0].length = 0; allocator->cells[0].length = 0;
} }
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align) void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align)
{ {
usize rsize = size; usize real_size = size;
align_to(rsize, 16); align_to(real_size, 16);
raw_allocator_cell *cell = allocator->cells; raw_allocator_cell *cell = allocator->cells;
while ((void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->size) while ((void *)raw_allocator_next_cell(cell) < (void *)allocator + allocator->size)
{ {
while ( while ( // 确保cell指向的内容还在这个allocator内
(void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->size && (void *)raw_allocator_next_cell(cell) < raw_allocator_end(allocator) &&
cell->length != 0) cell->length != 0)
{ {
cell = (void *)cell + cell->capacity + sizeof(raw_allocator_cell); cell = raw_allocator_next_cell(cell);
} }
if (rsize <= cell->capacity) if (real_size <= cell->capacity)
break; break;
} }
if ((void *)cell < (void *)allocator + allocator->size) if ((void *)cell < raw_allocator_end(allocator))
goto fitable_cell_finded; goto fitable_cell_finded;
else else
return nullptr; return nullptr;
fitable_cell_finded: fitable_cell_finded:
cell->length = size; cell->length = size;
if (rsize < cell->capacity) if (real_size < cell->capacity)
{ {
usize cap = cell->capacity; usize cap = cell->capacity;
cell->capacity = rsize; cell->capacity = real_size;
raw_allocator_cell *ncell = (void *)cell + cell->capacity + sizeof(raw_allocator_cell); raw_allocator_cell *ncell = raw_allocator_next_cell(cell);
ncell->capacity = cap - rsize - sizeof(raw_allocator_cell); ncell->capacity = cap - real_size - sizeof(raw_allocator_cell);
ncell->length = 0; ncell->length = 0;
} }
allocator->rest_memory -= real_size;
return cell->content; return cell->content;
} }
static inline void raw_allocator_cellmerge(raw_allocator_t *allocator)
{
raw_allocator_cell *cell = allocator->cells;
raw_allocator_cell *ncell = raw_allocator_next_cell(cell);
while ((void *)ncell < raw_allocator_end(allocator))
{
while ( // 首先保证ncell还在这个allocator内
(void *)ncell < raw_allocator_end(allocator) &&
cell->length == 0 && ncell->length == 0)
{
cell->capacity += ncell->capacity + sizeof(raw_allocator_cell);
ncell = raw_allocator_next_cell(ncell);
}
cell = ncell;
ncell = raw_allocator_next_cell(cell);
}
}
void raw_allocator_free(raw_allocator_t *allocator, void *mem) void raw_allocator_free(raw_allocator_t *allocator, void *mem)
{ {
raw_allocator_cell *cell = allocator->cells; raw_allocator_cell *cell = allocator->cells;
while ((void *)cell < (void *)allocator + allocator->size) while ((void *)cell < raw_allocator_end(allocator))
{ {
if (mem == cell->content) if (mem == cell->content)
{ {
cell->length = 0; cell->length = 0;
break; break;
} }
cell = (void *)cell + sizeof(raw_allocator_cell) + cell->capacity; cell = raw_allocator_next_cell(cell);
}
allocator->rest_memory += cell->capacity + sizeof(raw_allocator_cell);
allocator->free_count++;
if ( // 可用内存不超过当前allocator的 5% 或调用free次数很多时
allocator->size / allocator->rest_memory > 20 &&
allocator->free_count > RAW_ALLOCATOR_FREE_MAX)
{
raw_allocator_cellmerge(allocator);
allocator->free_count = 0;
} }
} }