加载中…
个人资料
IT视野
IT视野
  • 博客等级:
  • 博客积分:0
  • 博客访问:281,862
  • 关注人气:91
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

操作系统内存管理实验代码

(2011-05-27 00:20:45)
标签:

it

分类: Linux操作系统

//内存空闲分区的描述
#include <stdio.h>
#include <stdlib.h>
#include <malloc.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;                                     
int flag = 0;                         

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;

//
函数声明
struct free_block_type* init_free_block(int mem_size);
void display_menu();
int set_mem_size();
void set_algorithm();
void rearrange(int algorithm);
int rearrange_FF();
int rearrange_BF();
int rearrange_WF();
int new_process();
int allocate_mem(struct allocated_block *ab);
void kill_process();
int free_mem(struct allocated_block *ab);
int dispose(struct allocated_block *free_ab);
int display_mem_usage();
void do_exit();
struct allocated_block *find_process(int pid);


int main(){
    char choice;      pid=0;
    free_block = init_free_block(mem_size); //
初始化空闲区
    while(1) {
    display_menu(); //
显示菜单
    fflush(stdin);
    choice=getchar();   //
获取用户输入
    switch(choice){
        case '1': set_mem_size(); break;    //
设置内存大小
        case '2': set_algorithm();flag=1; break;//
设置算法
        case '3': new_process(); flag=1; break;//
创建新进程
        case '4': kill_process(); flag=1; break;//
删除进程
        case '5': display_mem_usage();   flag=1; break; //
显示内存使用
        case '0': do_exit(); exit(0);   //
释放链表并退出
        default: break;   
        }   
    }
    return 1;
}


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;
}


void display_menu(){
    printf("\n");
    printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
    printf("2 - Select memory allocation algorithm\n");
    printf("3 - New process \n");
    printf("4 - Terminate a process \n");
    printf("5 - Display memory usage \n");
    printf("0 - Exit\n");
}


int 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;
 }
   
 
void set_algorithm(){
    int algorithm;
    while(1) {
        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;
                break;
            }
        else
                printf("
输入有误,请重新输入!\n");
    }
    //
按指定算法重新排列空闲区链表
    rearrange(ma_algorithm);
} 


void rearrange(int algorithm){
    switch(algorithm){
        case MA_FF:  rearrange_FF(); break;
        case MA_BF:  rearrange_BF(); break;
        case MA_WF: rearrange_WF(); break;
        }
}
   

int rearrange_FF(){  
    struct free_block_type *temp;
    //
使用头插法,thead为临时头,p为最小地址的数据块的前一个结点
    struct free_block_type *thead=NULL,*p=NULL;
    //
当前的最小地址
    int min_addr = free_block->start_addr;
    temp = free_block;
   
    while(temp->next!=NULL) {
            if(temp->next->start_addr<min_addr) {
                min_addr = temp->next->start_addr;
                p = temp;
            }
            temp = temp->next; 
        }
        if(NULL!=p) {
            temp = p->next;
            p->next = p->next->next;
            temp->next = free_block;
            free_block = temp;
    }
//printf("2222222222\n");  
//printf("%d\n",free_block->start_addr);
   
    thead = free_block;
    p = free_block;
    temp = free_block->next;
    while(thead->next!=NULL) {
        min_addr = thead->next->start_addr;
        while(temp->next!=NULL) {
            if(temp->next->start_addr<min_addr) {
                min_addr = temp->next->start_addr;
                p = temp;
            }
            temp = temp->next; 
        }
        if(p->next!=thead->next) {
            temp = p->next;
            p->next = p->next->next;
            temp->next = thead->next;
            thead->next = temp;
        }
        thead = thead->next;
        p = thead;
        temp = thead->next;
    }
    //
请自行补充
    return 1;
}

int rearrange_BF(){
    struct free_block_type *temp;
    //
使用头插法,thead为临时头,p为最小内存的数据块的前一个结点
    struct free_block_type *thead=NULL,*p=NULL;
    //
当前的最小内存
    int min_size = free_block->size;
    temp = free_block;
   
    while(temp->next!=NULL) {
            if(temp->next->size<min_size) {
                min_size = temp->next->size;
                p = temp;
            }
            temp = temp->next; 
        }
        if(NULL!=p) {
            temp = p->next;
            p->next = p->next->next;
            temp->next = free_block;
            free_block = temp;
    }
   
    thead = free_block;
    p = free_block;
    temp = free_block->next;
    while(thead->next!=NULL) {
        min_size = thead->next->size;
        while(temp->next!=NULL) {
            if(temp->next->size<min_size) {
                min_size = temp->next->size;
                p = temp;
            }
            temp = temp->next; 
        }
        if(p->next!=thead->next) {
            temp = p->next;
            p->next = p->next->next;
            temp->next = thead->next;
            thead->next = temp;
        }
        thead = thead->next;
        p = thead;
        temp = thead->next;
    }
    //
请自行补充
    return 1;
}

int rearrange_WF(){
    struct free_block_type *temp;
    //
使用头插法,thead为临时头,p为最大内存的数据块的前一个结点
    struct free_block_type *thead=NULL,*p=NULL;
    //
当前的最大内存
    int max_size = free_block->size;
    temp = free_block;
   
    while(temp->next!=NULL) {
            if(temp->next->size>max_size) {
                max_size = temp->next->size;
                p = temp;
            }
            temp = temp->next; 
        }
        if(NULL!=p) {
            temp = p->next;
            p->next = p->next->next;
            temp->next = free_block;
            free_block = temp;
    }
   
    thead = free_block;
    p = free_block;
    temp = free_block->next;
   
    while(thead->next!=NULL) {
        max_size = thead->next->size;
        while(temp->next!=NULL) {
            if(temp->next->size>max_size) {
                max_size = temp->next->size;
                p = temp;
            }
            temp = temp->next; 
        }
        if(p->next!=thead->next) {
            temp = p->next;
            p->next = p->next->next;
            temp->next = thead->next;
            thead->next = temp;
        }
        thead = thead->next;
        p = thead;
        temp = thead->next;
    }
    //
请自行补充
    return 1;
}


int 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-d", pid);
    ab->pid = pid;   
    while(1) {
        printf("Memory for %s:", ab->process_name);
        scanf("%d", &size);
        if(size>0) {
            ab->size=size;
            break;
        }
        else printf("
输入大小有误,请重新输入\n");
    }
//printf("11111111111111\n");  
    ret = allocate_mem(ab); 
      
//printf("11111111111111\n");         
    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");
        pid--;
        free(ab);
        return -1;      
     }
    return 3;
}


int allocate_mem(struct allocated_block *ab){
    struct free_block_type *fbt, *pre,*head,*temp,*tt;
    struct allocated_block *tp;
    int request_size=ab->size;
    int sum=0;
    int max;
    head = (struct free_block_type *)malloc(sizeof(struct free_block_type));
    pre = head;
    fbt = free_block;
    pre->next = fbt;
//printf("11111111111111\n");      
    //
根据当前算法在空闲分区链表中搜索合适空闲分区进行分配,分配时注意以下情况:
    // 1.
找到可满足空闲分区且分配后剩余空间足够大,则分割
    // 2.
找到可满足空闲分区且但分配后剩余空间比较小,则一起分配
    // 3.
找不可满足需要的空闲分区但空闲分区之和能满足需要,则采用内存紧缩技术,进行空闲分区的合并,然后再分配
    // 4.
在成功分配内存后,应保持空闲分区按照相应算法有序
    // 5.
分配成功则返回1,否则返回-1
    if(ma_algorithm==MA_WF) {
        if(NULL==fbt||fbt->size<request_size)
            return -1;
    }
    else {
        while(NULL!=fbt&&fbt->size<request_size) {
            pre = fbt;
            fbt = fbt->next;
        }
    }
   
    if(NULL==fbt||fbt->size<request_size) {
       
        if(NULL!=free_block->next) {
            sum = free_block->size;
            temp = free_block->next;
            while(NULL!=temp) {
                sum += temp->size;
                if(sum>=request_size)
                    break;
                temp = temp->next;
            }
            if(NULL==temp)
                return -1;
            else {
                pre = free_block;
                max = free_block->start_addr;
                fbt = free_block;
                while(temp->next!=pre) {
                    if(max<pre->start_addr) {
                        max = pre->start_addr;
                        fbt = pre; 
                    }
                    pre = pre->next;
                }
                pre = free_block;  
                while(temp->next!=pre) {   
                    tp = allocated_block_head;
                    tt = free_block;
                    if(pre!=fbt) {
                        while(NULL!=tp) {
                            if(tp->start_addr>pre->start_addr)
                                tp->start_addr = tp->start_addr - pre->size;
                            tp = tp->next;     
                        }
                        while(NULL!=tt) {
                            if(tt->start_addr>pre->start_addr)
                                tt->start_addr = tt->start_addr - pre->size;
                            tt = tt->next; 
                        }
                    }
                    pre = pre->next;
                }
                pre = free_block;
                while(pre!=temp->next) {
                    if(pre!=fbt)
                        free(pre);
                    pre = pre->next;
                }
                free_block = fbt;
                free_block->size = sum;
                free_block->next = temp->next;
                if(free_block->size - request_size < MIN_SLICE) {
                    ab->size = free_block->size;
                    ab->start_addr = free_block->start_addr;
                    pre = free_block;
                    free_block = free_block->next;
                    free(pre);
                }
                else {
                    ab->start_addr = fbt->start_addr;
                    free_block->start_addr = free_block->start_addr + request_size;
                    free_block->size = free_block->size - request_size;
                }
            }  
        }
        else
            return -1; 
           
    }      
    else {
        //
将内存块全部分配
        if(fbt->size - request_size < MIN_SLICE) {
            ab->size = fbt->size;
            ab->start_addr = fbt->start_addr;
            if(pre->next==free_block) {
                free_block = fbt->next;
            }
            else   
                pre->next = fbt->next;
            free(fbt);
        }
        else {
            ab->start_addr = fbt->start_addr;
            fbt->start_addr = fbt->start_addr + request_size;
            fbt->size = fbt->size - request_size;
        }
    }
    free(head);
//printf("11111111111111\n");  
    rearrange(ma_algorithm);
    //
请自行补充。。。。。
    return 1;
}


void kill_process(){
    struct allocated_block *ab;
    int pid;
    printf("Kill Process, pid=");
    scanf("%d", &pid);
    ab = find_process(pid);
    if(ab!=NULL){
//printf("11111111111111\n");          
        free_mem(ab);
//printf("11111111111111\n");         
        dispose(ab); 
    }
    else {
        printf("
没有pid%d的进程!\n",pid);
    }
}

struct allocated_block *find_process(int pid) {
    struct allocated_block *ab=NULL;
    ab = allocated_block_head;
    while(NULL!=ab&&ab->pid!=pid)
        ab = ab->next;
    return ab;
}


int free_mem(struct allocated_block *ab){
    int algorithm = ma_algorithm;
    struct free_block_type *fbt, *pre=NULL,*head;
    fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
    pre=(struct free_block_type*) malloc(sizeof(struct free_block_type));
    if(!fbt) return -1;
    //
进行可能的合并,基本策略如下
    // 1.
将新释放的结点插入到空闲分区队列末尾
    // 2.
对空闲链表按照地址有序排列
    // 3.
检查并合并相邻的空闲分区
    // 4.
将空闲链表重新按照当前算法排序
    head = pre;
    fbt->start_addr = ab->start_addr;
    fbt->size = ab->size;
    fbt->next = free_block;  //
新释放的结点插入到空闲分区链表的表头
    free_block = fbt;    
    rearrange_FF();          //
对空闲链表按照地址有序排列
//printf("11111111111111\n");      
    pre->next = free_block;  //
求的prefbt的前一个结点
    pre->size = 0;
    while(pre->next->start_addr!=fbt->start_addr)
        pre = pre->next;
        //
左右分区都存在
    if(0!=pre->size&&NULL!=fbt->next) {
        //
左右分区都可合并
        if((pre->start_addr+pre->size)==fbt->start_addr && (fbt->start_addr+fbt->size)==fbt->next->start_addr) {
                pre->size = pre->size + fbt->size + fbt->next->size;
                pre->next = fbt->next->next;
                free(fbt->next);
                free(fbt);
        }
        //
左分区可合并
        else if((pre->start_addr+pre->size)==fbt->start_addr) {
                    pre->size = pre->size + fbt->size;
                    pre->next = fbt->next; 
                    free(fbt);
        }
        //
右分区可合并
        else if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {
                    fbt->size = fbt->size + fbt->next->size;
                    fbt->next = fbt->next->next;
                    free(fbt->next);
        }
    }
      //
左分区不存在
    else if(0==pre->size) {
            if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {
                fbt->size = fbt->size + fbt->next->size;
                fbt->next = fbt->next->next;
                free(fbt->next);
            }  
    }
    //
右分区不存在
    else if(NULL==fbt->next) {
            if((pre->start_addr+pre->size)==fbt->start_addr) {
                pre->size = pre->size + fbt->size;
                pre->next = fbt->next; 
                free(fbt);
            }
    }
//printf("33333333333\n"); 
    rearrange(algorithm);
    free(head);
    //
请自行补充……
    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;
}
  

int 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(" s s\n", "      start_addr", "       size");
    while(fbt!=NULL){
        printf(" d d\n", fbt->start_addr, fbt->size);
        fbt=fbt->next;
        }   
       
    printf("\nUsed Memory:\n");
    printf("s s s s\n", "PID", "ProcessName", "start_addr", " size");
    while(ab!=NULL){
        printf("d s d d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
        ab=ab->next;
        }
    printf("----------------------------------------------------------\n");
    return 0;
}
   
void do_exit() {
}       
  





 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有