#include "stdio.h"
#define MIN_SLICE 10 /*最小碎片的大小*/
#define MEM_SIZE 1024 /*默认内存的大小*/
#define MEM_START 0 /*默认内存的起始位置*/
/* 内存分配算法 */
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
int mem_size=MEM_SIZE; /*内存大小*/
int ma_alg = MA_FF; /*当前分配算法*/
static int pid=0; /*初始pid*/
/*内存空闲分区的描述*/
/*描述空闲分区的数据结构*/
typedef struct free_block_type
{
int size;
int start_addr;
struct free_block_type *next;
}f_Node,*f_block;
/*指向内存中空闲分区链表的首指针*/
f_block free_block=NULL;
/*描述已分配的内存块*/
/*分配给进程的分区的描述*/
typedef struct allocated_block
{
int pid;
int size;
int start_addr;
struct allocated_block *next;
}a_Node,*all_block;
/*进程分配内存块链表的首指针*/
all_block allocated_area = NULL;
void swap(int *a,int *b)
{
int c;
c=*a;
*a=*b;
*b=c;
}
/*初始化空闲块,默认为6块*/
init_free_block()
{
f_Node *s;
int i,n;
int size=MEM_SIZE;
int start=0;
printf("How many blocks do you want to divided?");
scanf("%d",&n);
for(i=1;i<n;i++)
{
s=(f_Node *)malloc(sizeof(f_Node));
s->size=size/2;
s->start_addr=start;
size=s->size;
start=start+s->size;
s->next=free_block;
free_block=s;
}
s=(f_Node *)malloc(sizeof(f_Node));
s->size=MEM_SIZE-start;
s->start_addr=start;
s->next=free_block;
free_block=s;
}
rearange(int maalgorithm)
{if(maalgorithm==1)rearrange_FF();
if(maalgorithm==2)rearrange_BF();
if(maalgorithm==3)rearrange_WF();
}
/* 设置当前的分配算法 */
set_algorithm()
{
int alg;
printf("choice the algorithm:\n");
printf("\t1 - First Fit\n");
printf("\t2 - Best Fit \n");
printf("\t3 - Worst Fit \n");
scanf("%d", &alg);
if(alg>=1 && alg <=3)
{ma_alg=alg;
/*按指定算法重新排列空闲区链表*/
rearange(ma_alg);
}
}
/*按FF算法重新整理内存空闲块链表*/
rearrange_FF()
{
f_Node *tmp, *work;
printf("Rearrange free blocks for FF \n");
tmp = free_block;
/*把原来的空闲区链表按地址递增的顺序重新排列*/
while(tmp!=NULL)
{ work = tmp->next;
while(work!=NULL)
{
if( work->start_addr < tmp->start_addr) /*地址递增*/
{ swap(&work->start_addr, &tmp->start_addr);
swap(&work->size, &tmp->size);
}
else
work=work->next;
}
tmp=tmp->next;
}
}
/*按BF算法重新整理内存空闲块链表*/
rearrange_BF()
{
f_Node *tmp, *work;
printf("Rearrange free blocks for BF \n");
tmp = free_block;
/*把原来的空闲区链表按大小递增的顺序重新排列*/
while(tmp!=NULL)
{ work = tmp->next;
while(work!=NULL)
{
if( work->size < tmp->size) /*大小递增*/
{ swap(&work->start_addr, &tmp->start_addr);
swap(&work->size, &tmp->size);
}
else
work=work->next;
}
tmp=tmp->next;
}
}
/*按WF算法重新整理内存空闲块链表*/
rearrange_WF()
{
f_Node *tmp, *work;
printf("Rearrange free blocks for WF \n");
tmp = free_block;
/*把原来的空闲区链表按大小递减的顺序重新排列*/
while(tmp!=NULL)
{ work = tmp->next;
while(work!=NULL)
{
if( work->size > tmp->size) /*大小递减*/
{ swap(&work->start_addr, &tmp->start_addr);
swap(&work->size, &tmp->size);
}
else
work=work->next;
}
tmp=tmp->next;
}
}
/*分配内存模块*/
int allocate_mem(struct allocated_block *ab)
{
f_Node *fbt, *pre;
int request_size=ab->size;
fbt = pre = free_block;
while(fbt!=NULL)
{
if(fbt->size>=request_size)
{
if((fbt->size-request_size)>MIN_SLICE)
{
ab->start_addr=fbt->start_addr;
fbt->size=fbt->size-request_size;
fbt->start_addr=fbt->start_addr+request_size;
}
else
{
ab->start_addr=fbt->start_addr;
ab->size=fbt->size;
if(fbt==free_block)
{
free_block=fbt->next;
free(fbt);
}
else
{
pre->next=fbt->next;
free(fbt);
}
}
return 1;
}
pre=fbt;
fbt=fbt->next;
}
return -1;
}
/*创建新的进程,主要是获取内存的申请数量*/
new_process()
{
char ch;
a_Node *ab;
int size;
int ret;
ab=(a_Node *)malloc(sizeof(a_Node));
if(!ab) exit(-5);
ab->next = NULL;
pid++;
printf(" \nPROCESS-%02d\n", pid);
ab->pid = pid;
printf("Input the process' size:");
scanf("%d", &size);
if(size>0) ab->size=size;
set_algorithm();
ret = allocate_mem(ab); /* 从空闲区分配内存,ret==1表示分配ok*/
/*如果此时已分配分区链表尚未空,则把ab作为第一个分配的分区*/
if (ret==1)
{
ab->next=allocated_area;
allocated_area=ab;
printf("process %d is comleted!\n",pid);
display_mem_usage();
printf("Do you want to receive its space?");
ch=getche();
if(ch=='y')
free_mem(ab);
else if(ch=='n')
{printf("\n");
getch();
}
return 1;
}
else if(ret==-1)
{ /*分配不成功*/
printf("Allocation fail\n");
free(ab);
return -1;
}
}
/*将ab所表示的分区归还,并进行可能的合并*/
int free_mem(struct allocated_block *ab)
{
int alg = ma_alg;
f_Node *fbt,*work;
fbt=(f_Node *)malloc(sizeof(f_Node));
fbt->size=ab->size;
fbt->start_addr=ab->start_addr;
/*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
fbt->next = free_block;
free_block=fbt;
rearrange_FF();
fbt=free_block;
while(fbt!=NULL)
{
if(ab->start_addr==fbt->start_addr)
{
if(fbt->start_addr+fbt->size==fbt->next->start_addr)
{
fbt->size+=fbt->next->size;
work=fbt->next;
fbt->next=fbt->next->next;
free(work);
break;
}
fbt=fbt->next;
}
}
allocated_area=ab->next;
free(ab);
rearange(ma_alg);
return 1;
}
/* 显示当前内存的使用情况,包括空闲区的情况和已经分配的情况 */
display_mem_usage()
{
f_Node *fbt=free_block;
a_Node *ab=allocated_area;
if(fbt==NULL)
return(-1);
printf("----------------------------------------------------------\n");
/* 显示空闲区 */
printf("Free Memory:\n");
printf("%20s %20s\n", " start_addr", " size");
while(fbt!=NULL)
{
printf("%20d %20d\n", fbt->start_addr, fbt->size);
fbt=fbt->next;
}
/* 显示已分配区 */
printf("\nUsed Memory:\n");
printf("%10s %10s %10s\n", "PID", "start_addr", " size");
while(ab!=NULL)
{
printf("%10d %10d %10d\n", ab->pid, ab->start_addr, ab->size);
ab=ab->next;
}
printf("----------------------------------------------------------\n");
return 0;
}
main()
{ char c;
int i,j;
printf("The memory's size is 1024\n");
init_free_block();
display_mem_usage();
while(1)
{printf("\nDoyou want to creat new process?\n");
c=getche();
getch();
if(c=='Y'||c=='y')
{new_process();
display_mem_usage();
getch();
}
else if(c=='n'||c=='N')
break;
}
printf("\nIt's Over!!!");
getch();
}