优化内存管理模块中raw allocator的内存利用效率
This commit is contained in:
parent
6f049d9ca2
commit
af179fc127
|
@ -11,17 +11,25 @@ typedef struct __raw_allocator_cell
|
|||
usize length; // 是实际使用的长度
|
||||
u8 content[0];
|
||||
} 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
|
||||
// 在分配时遇到第一个空cell时将紧随其后的空cell都合并掉
|
||||
//
|
||||
// 统计从上次细胞合并以来free的调用次数,当调用次数很多或可用空间不足时
|
||||
// 触发细胞合并。
|
||||
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_t;
|
||||
#define raw_allocator_end(allocator) ((void *)(allocator) + (allocator)->size)
|
||||
|
||||
void raw_allocator_new(raw_allocator_t *allocator, usize size);
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ void kmain(void *mb2_bootinfo)
|
|||
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
|
||||
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));
|
||||
|
||||
// 初始化内核日志模块
|
||||
|
||||
|
|
|
@ -7,54 +7,84 @@
|
|||
void raw_allocator_new(raw_allocator_t *allocator, usize 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;
|
||||
}
|
||||
|
||||
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align)
|
||||
{
|
||||
usize rsize = size;
|
||||
align_to(rsize, 16);
|
||||
usize real_size = size;
|
||||
align_to(real_size, 16);
|
||||
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 (
|
||||
(void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->size &&
|
||||
while ( // 确保cell指向的内容还在这个allocator内
|
||||
(void *)raw_allocator_next_cell(cell) < raw_allocator_end(allocator) &&
|
||||
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;
|
||||
}
|
||||
if ((void *)cell < (void *)allocator + allocator->size)
|
||||
if ((void *)cell < raw_allocator_end(allocator))
|
||||
goto fitable_cell_finded;
|
||||
else
|
||||
return nullptr;
|
||||
|
||||
fitable_cell_finded:
|
||||
cell->length = size;
|
||||
if (rsize < cell->capacity)
|
||||
if (real_size < cell->capacity)
|
||||
{
|
||||
usize cap = cell->capacity;
|
||||
cell->capacity = rsize;
|
||||
raw_allocator_cell *ncell = (void *)cell + cell->capacity + sizeof(raw_allocator_cell);
|
||||
ncell->capacity = cap - rsize - sizeof(raw_allocator_cell);
|
||||
cell->capacity = real_size;
|
||||
raw_allocator_cell *ncell = raw_allocator_next_cell(cell);
|
||||
ncell->capacity = cap - real_size - sizeof(raw_allocator_cell);
|
||||
ncell->length = 0;
|
||||
}
|
||||
allocator->rest_memory -= real_size;
|
||||
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)
|
||||
{
|
||||
raw_allocator_cell *cell = allocator->cells;
|
||||
while ((void *)cell < (void *)allocator + allocator->size)
|
||||
while ((void *)cell < raw_allocator_end(allocator))
|
||||
{
|
||||
if (mem == cell->content)
|
||||
{
|
||||
cell->length = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue