自己动手写操作系统(七)
程序员文章站
2024-03-24 11:46:40
...
今天主要分析coalition_allocator的内存分配流程。看过linux相关数据的同学都听说过kernel的buddy内存管理。实际上coalition内存分配的远离和buddy基本相同:将物理内存分为4k,8k,16k,32k......2的幂。例如,目前需要分配一个9k的内存,步骤如下:
========================================
1.调用GET_ALIGN_PAGE向上取整,最后变为申请一个16k的内存。
2.在16k的free_page_list查询是否有空余内存,如果有,直接返回该内存
3.如果16k的free_page_list中没有,则向上查询32k的free_page_list是否存在空余内存。
4.查到空余内存后,以64k为例子,直接将空余内存分割成16k和48k
5.48k继续调用_coalition_free_list_adjust去做调整。
========================================
代码如下:
void* _coalition_malloc(int type,uint32_t size)
{
align_result align_ret;
int addr_shift = sizeof(pmm_stamp);
if(type == PMM_TYPE_PMEM)
{
addr_shift = PAGE_SIZE;
}
GET_ALIGN_PAGE((size + addr_shift),&align_ret); //向上取整为2的n次幂
int alignsize = align_ret.page_size;
int order = align_ret.order;
list_head *p;
//we should first find whether there is unused memory
list_for_each(p,&normal_zone.nr_area[order].free_page_list) {//如果当前的存在剩余内存可用,直接返回即可
mm_page *page = list_entry(p,mm_page,ll);
//we get free page
list_del(p);
_coalition_list_add(p,&normal_zone.nr_area[order].used_page_list);
pmm_stamp *ret_stamp = (pmm_stamp *)page->start_pa;
ret_stamp->type = type;
return (void *)(page->start_pa + addr_shift);
}
order++;//没有找到剩余内存,继续向更大的内存队列查询
while(order < ZONE_FREE_MAX_ORDER)
{
int current_order = order;
if(!list_empty(&normal_zone.nr_area[order].free_page_list))
{
//hit we find a free page,split the page
list_for_each(p,&normal_zone.nr_area[order].free_page_list) {
mm_page *page = list_entry(p,mm_page,ll);
if(page->size < alignsize)
{
continue;
}
list_del(p);
if(page->size > alignsize)//发现当前的可用内存可以分配出制定的内存大小
{
pmm_stamp *stamp = (pmm_stamp *)(page->start_pa + alignsize);
mm_page *another = &stamp->page;
//kprintf("wangsl2,anotheris %x,alignsize is %x \n",another,alignsize);
another->start_pa = (addr_t)stamp;
another->size = page->size - alignsize;
align_result another_align_ret;
GET_ALIGN_PAGE(another->size,&another_align_ret); //todo
int move_order = another_align_ret.order;//将内存分为2块,一块就是所需要的内存,一块剩余内存放入free page list
_coalition_list_add(&another->ll,&normal_zone.nr_area[move_order].free_page_list);
_coalition_free_list_adjust(&another->ll,&normal_zone.nr_area[move_order].free_page_list);
//free page list重新做归并
page->size = alignsize;
current_order = align_ret.order;//GET_FREE_ORDER(alignsize);
}
_coalition_list_add(p,&normal_zone.nr_area[current_order].used_page_list);//已经使用的内存放入used数组
上一篇: Nodejs koa2读取服务器图片返回给前端直接展示
下一篇: 自己动手写操作系统(三)