关闭

xv6的buddy系统的源代码

519人阅读 评论(0) 收藏 举报

#include"buddy.h"

#include"defs.h"

free_area_t  free_area[MAX_ORDER];//定义free_area_t类型的free_area数组

struct Page*mem_map;

const int FreeAreaSize[MAX_ORDER]={1,2,4,8,16,32,64,128,256,512,1024};//定义数组FreeAreaSize

void test_buddy();

//check if pointer page  indicates the first page frame of a block of order_size pages

//if so ,return1 ,else return 0;

int page_is_buddy(struct Page *page,int order)//页是在buddy系统中

{

if(PageProperty(page)&&page->property==order&&!PageReserved(page))

return 1;

return 0;

void init_memmap_buddy(struct Page*base,unsigned long nr)//对初始化内存把空闲内存放到buddy系统上

{

 int i,order;

struct Page*page=base ;

mem_map=base;

for(i=0;i<MAX_ORDER;i++)

{

if(!LIST_EMPTY(&(free_area[i].free_list)))

panic("error");

}

while(nr)

{

for(order=10;order>=0;order--)//分配内存到buddy系统上

{

    if(nr>=FreeAreaSize[i])

    LIST_INSERT_HEAD(&(free_area[order].free_list),page,lru);

    free_area[order].nr_free++;

    page->property=order;

    nr-=FreeAreaSize[order];

   page+=FreeAreaSize[order];

    break;

}

}
}

//在buddy系统上寻找合适的空闲块分配给请求的大小

struct Page*alloc_pages_buddy(int nr)

{

struct Page*p;

for(i=0;i<MAX_ORDER;i++){

if(nr<frea_area[i])

{

  p=alloc_pages_buddy_bulk(i);

 dbmsg("cpu%xkalloc%x":order%d;/n",cpu(),p-pages,i);

  return p;

}

 

}

return NULL;

}

//implement  buddy system strategy for freeing page frame;

struct Page*alloc_pages_bulk_buddy(int order)

{

 int isalloc=0;

int current_order,size=0;

struct Page*page=NULL,*buddy=NULL;

for(current_order=order;current_order<MAX_ORDER;current_order++)

     if(!LIST_EMPTY(&(free_area[current_order].free_list)))

{

     isalloc=1;

     break;

}

if(!isalloc)

return NULL;

//找到空闲物理块然后分配出去

else{

 page=LIST_FIRST(&(free_area[current_order].free_list));

LIST_REMOVE(page,lru);

page->property=0;

ClearPageProperty(page);

free_area[current_order].nr_free--;

}

 

size=1<<current_order;

//从大到小进行折半操作

while(current_order>order)

{

 current_order--;

 size>>=1;

buddy=page+size;

 LIST_INSERT_HEAD(&(free_area[current_order].free_list),buddy,lru)

 buddy->property=current_order;

SetPageProperty(buddy);

free_area[current_order].nr_free++;

}

return page;

}

//按buddy系统的策略释放页框

//找到最贴近nr大小的FreeAreaSize[i],这时i是要和buddy系统上的伙伴合并的块的位置

void  free_pages_buddy(struct Page*page,int nr)

{int i;

 for(i=0;i<MAX_OEDER;i++)

  if(nr<FreeAreaSize[i])

  {

  dbmsg("kfree %x : order %d/n", page - pages, i);

   free_pages_bulk_buddy(page,i);

   return;

   }

}

}

//

void  free_pages_bulk_buddy(struct Page*page,int order)

{

 int size=1<<order;

unsigned long page_idx=page-mem_map,buddy_idx;

struct Page*buddy,*coalesced;

while(order<10)

{

  buddy_idx=size^page_idx;//找mem_map数组上page_idx的buddy;

  buddy=&mem_map[buddy_idx];//将buddy_idx为下标的数组的地址给buddy指针

 if(!page_is_buddy(buddy,order))

   break;

LIST_REMOVE(buddy,lru);//删除buddy上释放块的伙伴!

free_area[order].nr_free--;

 buddy->property=0;     //

ClearPageProperty(buddy);//

page_idx&=buddy_idx;

 order++;

size>>1;

}

coalesced=&mem_map[page_idx];
     dbmsg("free order %x,page %x/n",order,coalesced-pages);
     coalesced->property=order;
     SetPageProperty(coalesced);
     LIST_INSERT_HEAD(&(free_area[order].free_list),coalesced,lru);
     free_area[order].nr_free++;

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21123次
    • 积分:380
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章存档