优化内存管理模块中raw allocator的内存利用效率
This commit is contained in:
parent
6f049d9ca2
commit
af179fc127
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
// 初始化内核日志模块
|
// 初始化内核日志模块
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue