操作系统上机实验(三)存储管理——动态不等长存储资源分配算法

前言:
笔者水平有限,有错误之处欢迎指出。
思考题没有答案,因为笔者自己的思考题也随便乱写乱copy,就不放出来祸害别人了
本文首发于个人博客,地址https://txaxsimer.github.io
(该博客已停用,最新地址
https://hexo-delta-brown.vercel.app/2022/06/16/操作系统上机实验(三)存储管理——动态不等长存储资源分配算法/)

实验目的

理解动态异长存储分区资源管理,掌握所需数据结构和管理程序,了解各种存储分配算法的优点和缺点。

实验内容

分析UNIX最先适应(FF)存储分配算法,即map数据结构、存储分配函数malloc()和存储释放函数mfree(),找出与算法有关的成分。
修改上述与算法有关的成分,使其分别体现BF分配原则和WF分配原则。

实验设计

按内容要求编写最佳适应和最坏适应存储分配算法。
编写测试程序,对存储分配表进行初始化。然后对用户输入的请求和释放,按算法动态更新存储分配表,并将每次更新之后的存储分配表在屏幕上显示出来。

参考代码

跑不起来所以简单改了一些地方

#ifdef  HAVE_CONFIG_H
#include  <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#define MAPSIZE 100
struct map  //存储资源表结构
{
    int m_addr;
    int m_size;
};
struct map map[MAPSIZE];  //存储资源表
//BF存储分配函数
int BF_malloc(struct map *mp,int size)  
{
    register int a,s;
    register struct map *bp,*bpp;
    for(bp = mp; bp->m_size; bp++)
    {
       if (bp->m_size >= size)
        {
            a = bp->m_addr;
            s = bp->m_size;
            for(bpp = bp; bpp->m_size; bpp++)
            {   //最佳适应
                if(bpp->m_size >= size && bpp->m_size < s)
                {
                    a = bpp->m_addr;
                    s = bpp->m_size;
                    bp = bpp;
                }
            }
            
            bp->m_addr += size;
            if ((bp->m_size -= size) == 0)
                do
                {
                    bp++;
                    (bp-1)->m_addr = bp->m_addr;
                }
                while((bp-1)->m_size = bp->m_size);
            return(a);
        }
    }
    return(-1);
}

//WF存储分配函数
int WF_malloc(struct map *mp,int size) 
{
    register int a,s;
    register struct map *bp,*bpp;
    for(bp = mp; bp->m_size; bp++)
    {
        if (bp->m_size >= size)
        {
            a = bp->m_addr;
            s = bp->m_size;
            for(bpp = bp; bpp->m_size; bpp++) 
            {   //最坏适应
                if(bpp->m_size > s) 
                {
                    a = bpp->m_addr;
                    s = bpp->m_size;
                    bp = bpp;
                }
            }
bp->m_addr += size;
            if ((bp->m_size -=size) == 0)
                do
                {
                    bp++;
                    (bp-1)->m_addr = bp->m_addr;
                }
                while((bp-1)->m_size = bp->m_size);
            return(a);
        }
    }
    return(-1);
}

//存储释放函数
void mfree(struct map *mp,int aa,int size) 
{
    register struct map *bp;
    register int t;
    register int a;
    a = aa;
    for(bp = mp; bp->m_addr<=a && bp->m_size != 0; bp++)
        ;
    if(bp>mp && (bp-1)->m_addr+(bp-1)->m_size==a)
    {  //与前合并
         (bp-1)->m_size += size;
         if (a+size == bp->m_addr)
         {   //前后合并
              (bp-1)->m_size += bp->m_size;
              while (bp->m_size)
              {
                  bp++;
                  (bp-1)->m_addr = bp->m_addr;
                  (bp-1)->m_size = bp->m_size;
              }
         }
    }

else
    {
         if (a+size == bp->m_addr && bp->m_size)
         {   //与后合并
              bp->m_addr -= size;
              bp->m_size += size;
         }
         else if (size)
              do
              {   //无合并
                   t = bp->m_addr;
                   bp->m_addr = a;
                   a = t;
                   t = bp->m_size;
                   bp->m_size = size;
                   bp++;
              }
              while (size = t);
    }
}
void init()
{
    struct map *bp;
    int addr,size;
    int i=0;
    bp=map;
    printf("Please input starting addr and total size:");
    scanf("%d,%d",&addr,&size);
    bp->m_addr=addr;
    bp->m_size=size;
    (++bp)->m_size=0;  //表尾
}

void show_map()
{
     int i=0;
     //system("clear");  //清屏
     struct map *bp;
     bp=map;
     printf("\nCurrent memory map...\n");
     printf("Address\t\tSize\n");
     while(bp->m_size!=0)
     {
         printf("<%d\t\t%d>\n",bp->m_addr,bp->m_size);
	    bp++;
     }
     printf("\n");
}
int main()
{
    int a,s;
    char c;
    int i;
    init();
    getchar();
    printf("please input, b for BF, w for WF:");
    scanf("%c",&c);
    do
    {
        show_map(); //显示存储资源表
        //printf("please input, b for BF, w for WF, e for exit\n");
        printf("Please input,1 for request,2 for release,0 for exit:");
        scanf("%d",&i);
        switch(i)
        {
            case 1:
                printf("Please input size:");
                scanf("%d", &s);
                if(c=='b') //BF
                    a=BF_malloc(map,s);
                else  //WF
                    a=WF_malloc(map,s);
                if(a==-1)
                    printf("request can't be satisfied\n");
                else
                    printf("alloc memory at address:%d,size:%d\n",a,s);
                break;
            case 2:
                printf("Please input addr and size:");
                scanf("%d,%d",&a,&s);
                mfree(map,a,s);
                break;
            case 0:
                exit(0);
        }
    }
    while(1);
}

实验结果

在这里插入图片描述
在这里插入图片描述

思考题
  • 上述算法沿用了UNIX系统所采用的数据结构,存储分配表中空闲区按m_addr递增排列,对于任意请求,需要由表头查到表尾才能确定最佳(最坏)分配区域。为提高存储分配时的查找速度,有人将表中空闲区按m_size递增(递减)排列,这样分配时取第一个长度能满足的表项即可。采用这种组织方式,不仅分配后剩余部分在表中的位置可能发生变化,而且需对释放函数进行较大的修改,试给出对应的算法
  • 对于Linux系统采用的伙伴堆(buddy heap)内存资源管理,设计相应的数据结构和算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值