diff --git a/src/include/kernel/memm/allocator/raw.h b/src/include/kernel/memm/allocator/raw.h index 8f84c09..b2f00b3 100644 --- a/src/include/kernel/memm/allocator/raw.h +++ b/src/include/kernel/memm/allocator/raw.h @@ -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); diff --git a/src/kernel/main.c b/src/kernel/main.c index 9da9895..42ebb71 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -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)); // 初始化内核日志模块 diff --git a/src/kernel/memm/allocator/raw.c b/src/kernel/memm/allocator/raw.c index ab92cf6..79ed4e8 100644 --- a/src/kernel/memm/allocator/raw.c +++ b/src/kernel/memm/allocator/raw.c @@ -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; } }