#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<ctype.h>
#include<pthread.h>
#define PROCESS_NAME_LEN 32 /*进程名称的最大长度*/
#define MIN_SLICE 10 /*最小碎片的大小*/
#define DEFAULT_MEM_SIZE 1024 /*默认内存的大小*/
#define DEFAULT_MEM_START 0 /*默认内存的起始位置*/
/* 内存分配算法 */
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
int mem_size=DEFAULT_MEM_SIZE; /*内存大小*/
int ma_algorithm = MA_FF; /*当前分配算法*/
static int pid = 0; /*初始pid*/
int flag = 0;
int algorithm;
struct free_block_type{
int size;
int start_addr;
struct free_block_type *next;
};
struct free_block_type *free_block;/*指向内存快空闲链表首指针*/
struct allocated_block{/*每个进程分配到内存快*/
int pid;
int size;
int start_addr;
char process_name[PROCESS_NAME_LEN];
struct allocated_block *next;
};
struct allocated_block *allocated_block_head = NULL;
void do_exit(){
exit(0);
}
struct free_block_type* init_free_block(int mem_size){
struct free_block_type *fb;//申请空间
fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));
if(fb==NULL){
printf("No mem\n");
return NULL;
}
fb->size = mem_size;
fb->start_addr = DEFAULT_MEM_START;
fb->next = NULL;
return fb;
}
display_menu(){
printf("\n");
printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
printf("2 - Select memory allocation algorithm选择合适的空间分配suanfa\n");
printf("3 - New process 创建信进程\n");
printf("4 - Terminate a process删除进程 \n");
printf("5 - Display memory usage 展示使用情况\n");
printf("0 - Exit\n");
}
set_mem_size(){//设置空间大小
int size;
if(flag!=0){ //防止重复设置
printf("Cannot set memory size again\n");
return 0;
}
printf("Total memory size =");
scanf("%d", &size);
if(size>0) {
mem_size = size;
free_block->size = mem_size;
}
flag=1; return 1;
}
rearrange_FF(){
struct free_block_type *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;
}
}
rearrange_BF(){
struct free_block_type *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(){
struct free_block_type *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;
}
}
//按指定算法重新排列空闲区链表
rearrange(int algorithm){
switch(algorithm){
case MA_FF: rearrange_FF(); break;
case MA_BF: rearrange_BF(); break;
case MA_WF: rearrange_WF(); break;
}
}
set_algorithm(){//选择当前的分配算法
int algorithm;
printf("\t1 - First Fit\n");
printf("\t2 - Best Fit \n");
printf("\t3 - Worst Fit \n");
scanf("%d", &algorithm);
if(algorithm>=1 && algorithm <=3) ma_algorithm=algorithm;
rearrange(ma_algorithm);
}
int free_mem(struct allocated_block *ab){
int algorithm = ma_algorithm;
struct free_block_type *fbt, *pre, *work;
fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
if(!fbt) return -1;
fbt->size = ab->size;
fbt->start_addr = ab->start_addr;
/*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
fbt->next = free_block;
free_block=fbt;
rearrange(MA_FF);
fbt=free_block;
while(fbt!=NULL){
work = fbt->next;
if(work!=NULL){
/*如果当前空闲区与后面的空闲区相连,则合并*/
if(fbt->start_addr+fbt->size == work->start_addr){
fbt->size += work->size;
fbt->next = work->next;
free(work);
continue;
}
}
fbt = fbt->next;
}
rearrange(algorithm); /*重新按当前的算法排列空闲区*/
return 1;
}
int allocate_mem(struct allocated_block *ab){
struct free_block_type *fbt, *pre,*temp,*work;
int request_size=ab->size;
fbt = pre = free_block;
while(fbt!=NULL){
if(fbt->size>=request_size){/*分配后空闲空间足够大,则分割*/
if(fbt->size-request_size>=MIN_SLICE){
mem_size-=request_size;
fbt->size-=request_size;
ab->start_addr=fbt->start_addr;
fbt->start_addr=ab->start_addr+request_size;
}
else if(fbt->size-request_size<MIN_SLICE&&(fbt->size-request_size>0)){/*分割后空闲区成为小碎片,一起分配*/
mem_size-=fbt->size;
pre=fbt->next;
ab->start_addr=fbt->start_addr;
fbt->start_addr+=fbt->size;
free(fbt);
}
else{
temp=free_block;
while(temp!=NULL){
work=temp->next;
if(work!=NULL){
if(temp->start_addr+temp->size==work->start_addr){//当前空闲区与后面空闲区相连则合并
temp->size+=work->size;
temp->next=work->next;
free(work);continue;
}
}
temp=temp->next;
}
fbt=free_block;
break;
}
rearrange(ma_algorithm);
return 1;
}
pre=fbt;
fbt=fbt->next;
}
return -1;
}
new_process(){
struct allocated_block *ab;
int size;
int ret;
ab=(struct allocated_block *)malloc(sizeof(struct allocated_block));
if(!ab) exit(-5);
ab->next = NULL;
pid++;
sprintf(ab->process_name, "PROCESS-%02d", pid);
ab->pid = pid;
printf("Memory for %s:", ab->process_name);
printf("请输入进程大小:\n");
scanf("%d", &size);
if(size>0) ab->size=size;
ret = allocate_mem(ab); /* 从空闲区分配内存,ret==1表示分配ok*/
/*如果此时allocated_block_head尚未赋值,则赋值*/
if((ret==1) &&(allocated_block_head == NULL)){
allocated_block_head=ab;
return 1;
}
/*分配成功,将该已分配块的描述插入已分配链表*/
else if (ret==1) {
ab->next=allocated_block_head;
allocated_block_head=ab;
return 2;
}
else if(ret==-1){ /*分配不成功*/
printf("Allocation fail\n");
free(ab);
return -1;
}
return 3;
}
/*将ab所表示的已分配区归还,并进行可能的合并*/
int free_men(struct allocated_block *ab){
int algorithm = ma_algorithm;
struct free_block_type *fbt, *pre, *work;
fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
if(!fbt) return -1;
fbt->size = ab->size;
fbt->start_addr = ab->start_addr;
/*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
fbt->next = free_block;
free_block=fbt;
rearrange(MA_FF);
fbt=free_block;
while(fbt!=NULL){
work = fbt->next;
if(work!=NULL){
/*如果当前空闲区与后面的空闲区相连,则合并*/
if(fbt->start_addr+fbt->size == work->start_addr){
fbt->size += work->size;
fbt->next = work->next;
free(work);
continue;
}
}
fbt = fbt->next;
}
rearrange(algorithm); /*重新按当前的算法排列空闲区*/
return 1;
}
int dispose(struct allocated_block *free_ab){
struct allocated_block *pre, *ab;
if(free_ab == allocated_block_head) { /*如果要释放第一个节点*/
allocated_block_head = allocated_block_head->next;
free(free_ab);
return 1;
}
pre = allocated_block_head;
ab = allocated_block_head->next;
while(ab!=free_ab){ pre = ab; ab = ab->next; }
pre->next = ab->next;
free(ab);
return 2;
}
void swap(int *p,int *q){
int temp;
temp=*p;
*p=*q;
*q=temp;
return;
}
display_mem_usage(){
struct free_block_type *fbt=free_block;
struct allocated_block *ab=allocated_block_head;
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 %20s %10s %10s\n", "PID", "ProcessName", "start_addr", " size");
while(ab!=NULL){
printf("%10d %20s %10d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
ab=ab->next;
}
printf("----------------------------------------------------------\n");
return 0;
}
struct allocated_block *find_process(int pid){
struct allocated_block *p;
p=allocated_block_head;
while(p){
if(p->pid==pid){
return p;
break;
}
else p=p->next;}
}
kill_process(){
struct allocated_block *ab;
int pid;
printf("Kill Process, pid=");
scanf("%d", &pid);
ab=find_process(pid);
if(ab!=NULL){
free_mem(ab); /*释放ab所表示的分配区*/
dispose(ab); /*释放ab数据结构节点*/
}
}
main(){
char choice;
pid=0;
free_block = init_free_block(mem_size); //初始化空闲区
for(;;){
display_menu(); //显示菜单
fflush(stdin);
choice=getchar(); //获取用户输入
switch(choice){
case '1': set_mem_size();getchar(); break; //设置内存大小
case '2': set_algorithm();flag=1;getchar(); break; //设置分配算法
case '3': new_process(); flag=1;getchar(); break; //创建新进程
case '4': kill_process(); flag=1;getchar(); break; //删除进程
case '5': display_mem_usage();getchar(); flag=1; break; //显示内存使用
case '0': do_exit(); exit(0); //释放链表并退出
default: break;
}
}
}
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<ctype.h>
#include<pthread.h>
#define PROCESS_NAME_LEN 32 /*进程名称的最大长度*/
#define MIN_SLICE 10 /*最小碎片的大小*/
#define DEFAULT_MEM_SIZE 1024 /*默认内存的大小*/
#define DEFAULT_MEM_START 0 /*默认内存的起始位置*/
/* 内存分配算法 */
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
int mem_size=DEFAULT_MEM_SIZE; /*内存大小*/
int ma_algorithm = MA_FF; /*当前分配算法*/
static int pid = 0; /*初始pid*/
int flag = 0;
int algorithm;
struct free_block_type{
int size;
int start_addr;
struct free_block_type *next;
};
struct free_block_type *free_block;/*指向内存快空闲链表首指针*/
struct allocated_block{/*每个进程分配到内存快*/
int pid;
int size;
int start_addr;
char process_name[PROCESS_NAME_LEN];
struct allocated_block *next;
};
struct allocated_block *allocated_block_head = NULL;
void do_exit(){
exit(0);
}
struct free_block_type* init_free_block(int mem_size){
struct free_block_type *fb;//申请空间
fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));
if(fb==NULL){
printf("No mem\n");
return NULL;
}
fb->size = mem_size;
fb->start_addr = DEFAULT_MEM_START;
fb->next = NULL;
return fb;
}
display_menu(){
printf("\n");
printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
printf("2 - Select memory allocation algorithm选择合适的空间分配suanfa\n");
printf("3 - New process 创建信进程\n");
printf("4 - Terminate a process删除进程 \n");
printf("5 - Display memory usage 展示使用情况\n");
printf("0 - Exit\n");
}
set_mem_size(){//设置空间大小
int size;
if(flag!=0){ //防止重复设置
printf("Cannot set memory size again\n");
return 0;
}
printf("Total memory size =");
scanf("%d", &size);
if(size>0) {
mem_size = size;
free_block->size = mem_size;
}
flag=1; return 1;
}
rearrange_FF(){
struct free_block_type *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;
}
}
rearrange_BF(){
struct free_block_type *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(){
struct free_block_type *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;
}
}
//按指定算法重新排列空闲区链表
rearrange(int algorithm){
switch(algorithm){
case MA_FF: rearrange_FF(); break;
case MA_BF: rearrange_BF(); break;
case MA_WF: rearrange_WF(); break;
}
}
set_algorithm(){//选择当前的分配算法
int algorithm;
printf("\t1 - First Fit\n");
printf("\t2 - Best Fit \n");
printf("\t3 - Worst Fit \n");
scanf("%d", &algorithm);
if(algorithm>=1 && algorithm <=3) ma_algorithm=algorithm;
rearrange(ma_algorithm);
}
int free_mem(struct allocated_block *ab){
int algorithm = ma_algorithm;
struct free_block_type *fbt, *pre, *work;
fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
if(!fbt) return -1;
fbt->size = ab->size;
fbt->start_addr = ab->start_addr;
/*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
fbt->next = free_block;
free_block=fbt;
rearrange(MA_FF);
fbt=free_block;
while(fbt!=NULL){
work = fbt->next;
if(work!=NULL){
/*如果当前空闲区与后面的空闲区相连,则合并*/
if(fbt->start_addr+fbt->size == work->start_addr){
fbt->size += work->size;
fbt->next = work->next;
free(work);
continue;
}
}
fbt = fbt->next;
}
rearrange(algorithm); /*重新按当前的算法排列空闲区*/
return 1;
}
int allocate_mem(struct allocated_block *ab){
struct free_block_type *fbt, *pre,*temp,*work;
int request_size=ab->size;
fbt = pre = free_block;
while(fbt!=NULL){
if(fbt->size>=request_size){/*分配后空闲空间足够大,则分割*/
if(fbt->size-request_size>=MIN_SLICE){
mem_size-=request_size;
fbt->size-=request_size;
ab->start_addr=fbt->start_addr;
fbt->start_addr=ab->start_addr+request_size;
}
else if(fbt->size-request_size<MIN_SLICE&&(fbt->size-request_size>0)){/*分割后空闲区成为小碎片,一起分配*/
mem_size-=fbt->size;
pre=fbt->next;
ab->start_addr=fbt->start_addr;
fbt->start_addr+=fbt->size;
free(fbt);
}
else{
temp=free_block;
while(temp!=NULL){
work=temp->next;
if(work!=NULL){
if(temp->start_addr+temp->size==work->start_addr){//当前空闲区与后面空闲区相连则合并
temp->size+=work->size;
temp->next=work->next;
free(work);continue;
}
}
temp=temp->next;
}
fbt=free_block;
break;
}
rearrange(ma_algorithm);
return 1;
}
pre=fbt;
fbt=fbt->next;
}
return -1;
}
new_process(){
struct allocated_block *ab;
int size;
int ret;
ab=(struct allocated_block *)malloc(sizeof(struct allocated_block));
if(!ab) exit(-5);
ab->next = NULL;
pid++;
sprintf(ab->process_name, "PROCESS-%02d", pid);
ab->pid = pid;
printf("Memory for %s:", ab->process_name);
printf("请输入进程大小:\n");
scanf("%d", &size);
if(size>0) ab->size=size;
ret = allocate_mem(ab); /* 从空闲区分配内存,ret==1表示分配ok*/
/*如果此时allocated_block_head尚未赋值,则赋值*/
if((ret==1) &&(allocated_block_head == NULL)){
allocated_block_head=ab;
return 1;
}
/*分配成功,将该已分配块的描述插入已分配链表*/
else if (ret==1) {
ab->next=allocated_block_head;
allocated_block_head=ab;
return 2;
}
else if(ret==-1){ /*分配不成功*/
printf("Allocation fail\n");
free(ab);
return -1;
}
return 3;
}
/*将ab所表示的已分配区归还,并进行可能的合并*/
int free_men(struct allocated_block *ab){
int algorithm = ma_algorithm;
struct free_block_type *fbt, *pre, *work;
fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
if(!fbt) return -1;
fbt->size = ab->size;
fbt->start_addr = ab->start_addr;
/*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
fbt->next = free_block;
free_block=fbt;
rearrange(MA_FF);
fbt=free_block;
while(fbt!=NULL){
work = fbt->next;
if(work!=NULL){
/*如果当前空闲区与后面的空闲区相连,则合并*/
if(fbt->start_addr+fbt->size == work->start_addr){
fbt->size += work->size;
fbt->next = work->next;
free(work);
continue;
}
}
fbt = fbt->next;
}
rearrange(algorithm); /*重新按当前的算法排列空闲区*/
return 1;
}
int dispose(struct allocated_block *free_ab){
struct allocated_block *pre, *ab;
if(free_ab == allocated_block_head) { /*如果要释放第一个节点*/
allocated_block_head = allocated_block_head->next;
free(free_ab);
return 1;
}
pre = allocated_block_head;
ab = allocated_block_head->next;
while(ab!=free_ab){ pre = ab; ab = ab->next; }
pre->next = ab->next;
free(ab);
return 2;
}
void swap(int *p,int *q){
int temp;
temp=*p;
*p=*q;
*q=temp;
return;
}
display_mem_usage(){
struct free_block_type *fbt=free_block;
struct allocated_block *ab=allocated_block_head;
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 %20s %10s %10s\n", "PID", "ProcessName", "start_addr", " size");
while(ab!=NULL){
printf("%10d %20s %10d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
ab=ab->next;
}
printf("----------------------------------------------------------\n");
return 0;
}
struct allocated_block *find_process(int pid){
struct allocated_block *p;
p=allocated_block_head;
while(p){
if(p->pid==pid){
return p;
break;
}
else p=p->next;}
}
kill_process(){
struct allocated_block *ab;
int pid;
printf("Kill Process, pid=");
scanf("%d", &pid);
ab=find_process(pid);
if(ab!=NULL){
free_mem(ab); /*释放ab所表示的分配区*/
dispose(ab); /*释放ab数据结构节点*/
}
}
main(){
char choice;
pid=0;
free_block = init_free_block(mem_size); //初始化空闲区
for(;;){
display_menu(); //显示菜单
fflush(stdin);
choice=getchar(); //获取用户输入
switch(choice){
case '1': set_mem_size();getchar(); break; //设置内存大小
case '2': set_algorithm();flag=1;getchar(); break; //设置分配算法
case '3': new_process(); flag=1;getchar(); break; //创建新进程
case '4': kill_process(); flag=1;getchar(); break; //删除进程
case '5': display_mem_usage();getchar(); flag=1; break; //显示内存使用
case '0': do_exit(); exit(0); //释放链表并退出
default: break;
}
}
}