编写伙伴算法
本程序实现了基本的伙伴算法。设计步骤:
(1)、初始化:把4096个页全部分配到最高等级的空闲区上。
(2)、分配算法:用户输入作业名和作业所需要的页数,该算法会根据伙伴算法的思想一级一级的找到合适的页框块。然后把该块的相关信息填写在已分配分区中。
(3)、回收算法:未分配算法的逆算法:用户输入作业名后,先根据作业名在分配区找到页框块,然后根据伙伴算法的思想一级一级的进行合并。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
struct PageBlock
{
char Job[20];
int begin_page;
int end_page;
int block_num;
struct PageBlock* link;
};
typedef struct PageBlock page_block;
struct FreeArea
{
page_block* free_list;
int nr_free;
} free_area[11];
page_block* used;
page_block* fp;
page_block* per;
void Insert(page_block* head, page_block* b, int k)
{
if(head->link == NULL)
{
head->link = b;
b->link=NULL;
}
else
{
page_block *ptr1 = head;
while(ptr1->link != NULL)
{
ptr1=ptr1->link;
}
ptr1->link = b;
b->link = NULL;
}
b->block_num=(b->end_page+1)/pow(2,k);
}
int IsPaFree(int block_num, int k)
{
int pa;
if(block_num%2 == 0)
pa = block_num-1;
else
pa = block_num+1;
page_block* pt=free_area[k].free_list;
page_block* pt1=pt->link;
while(pt1 != NULL)
{
if(pt1->block_num == pa)
break;
pt=pt->link;
pt1=pt->link;
}
if(pt1 == NULL)
return 0;
else
{
pt->link = pt1->link;
fp=pt1;
return 1;
}
}
void Init()
{
used=(page_block*)malloc(sizeof(page_block));
int i = 0;
for(i = 0; i < 11; i++)
{
free_area[i].free_list = (page_block*)malloc(sizeof(page_block));
free_area[i].free_list->link=NULL;
free_area[i].nr_free=0;
}
for(i = 0; i < 4; i++)
{
page_block* b1 = (page_block*)malloc(sizeof(page_block));
b1->begin_page=i*1024;
b1->end_page=(i+1)*1024-1;
Insert(free_area[10].free_list, b1,10);
free_area[10].nr_free++;
}
}
void alloct(char Job[], int pages)
{
int order ;
if(pages != 1)
order = log2(pages-1)+1;
else
order = 1;
int i = order;
for(i=order; i < 11; i++)
{
if(free_area[i].nr_free != 0)
break;
}
page_block* ptr = free_area[i].free_list->link;
free_area[i].free_list->link=ptr->link;
free_area[i].nr_free--;
i--;
while(i != order-1)
{
page_block* ptr1 =(page_block*)malloc(sizeof(page_block));
ptr1->begin_page=ptr->begin_page;
ptr1->end_page=ptr1->begin_page+pow(2,i)-1;
ptr1->link=NULL;
Insert(free_area[i].free_list,ptr1,i);
free_area[i].nr_free++;
ptr->begin_page=ptr1->end_page+1;
ptr->block_num=(ptr->end_page+1)/pow(2,i);
i--;
}
strcpy(ptr->Job,Job);
Insert(used, ptr,order);
}
void reclaim(char Job[])
{
page_block* ptr=used;
page_block* ptr1=ptr->link;
while(ptr1 != NULL)
{
if(strcmp(ptr1->Job,Job) == 0)
break;
ptr=ptr->link;
ptr1=ptr->link;
}
if(ptr1 == NULL)
{
printf("没有改作业\n");
return;
}
ptr->link=ptr1->link;
int o=ptr1->end_page-ptr1->begin_page+1;
int order = log2(o-1)+1;
if(IsPaFree(ptr1->block_num, order)==0)
{
Insert(free_area[order].free_list,ptr1,order);
}
else
{
int i = order;
while(i<10)
{
page_block* newblock=ptr1;
if(ptr1->block_num < fp->block_num)
{
newblock->end_page=fp->end_page;
free(fp);
}
else
{
newblock->begin_page=fp->begin_page;
free(fp);
}
free_area[i].nr_free--;
i++;
int block_num=(newblock->end_page+1)/pow(2,i);
if( i==10 || IsPaFree(block_num, i)==0)
{
Insert(free_area[i].free_list,newblock,i);
free_area[i].nr_free++;
break;
}
else
ptr1 = newblock;
}
}
}
void show()
{
printf("已分配分区:\n");
printf("作业名\t分区的起始页\t分区的终止页\t伙伴号\n");
page_block* ptr=used;
page_block* ptr1=ptr->link;
while(ptr1!=NULL)
{
printf("%s\t%d\t\t%d\t\t%d\n",ptr1->Job,ptr1->begin_page,ptr1->end_page,ptr1->block_num);
ptr=ptr->link;
ptr1=ptr->link;
}
printf("空闲分区\n");
printf("分区等级\t分区的起始页\t分区的终止页\t伙伴号\n");
int i = 0;
for(i = 10; i>=0; i--)
{
if(free_area[i].nr_free != 0)
{
page_block* ptr2=free_area[i].free_list;
page_block* ptr3=ptr2->link;
while(ptr3 != NULL)
{
printf("%d\t\t%d\t\t%d\t\t%d\n",i,ptr3->begin_page,ptr3->end_page,ptr3->block_num);
ptr2=ptr2->link;
ptr3=ptr2->link;
}
}
printf("\n");
}
}
int main()
{
Init();
int d = 0;
while(1)
{
system("cls");
printf("\n\n");
printf("\t\t请输入选项:\n");
printf("\t\t1.分配内存\n");
printf("\t\t2.回收内存\n");
printf("\t\t3.显示分配区\n");
printf("\t\t0.退出系统\n");
scanf("%d",&d);
if(d == 1)
{
printf("请输入要分配的作业名及大小(单位:页):\n");
char Job[10];
int pages;
scanf("%s%d",Job, &pages);
alloct(Job, pages);
getchar();
}
else if(d == 2)
{
printf("请输入要回收的作业名\n");
char Job[10];
scanf("%s",Job);
reclaim(Job);
getchar();
}
else if(d == 3)
{
show();
getchar();
}
else if(d == 0)
{
exit(0);
}
getchar();
}
return 0;
}