⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainclass.cpp

📁 用VC开发的模拟操作系统的页面置换
💻 CPP
字号:
// MainClass.cpp: implementation of the CMainClass class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "WIN页面置换.h"
#include "MainClass.h"

#include "MainClass.h"
#include "stdio.h"
#include <stdlib.h>
#include "iostream.h"
#include "time.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMainClass::CMainClass()
{
  m_program=NULL;      //程序,划分为多个页面
  m_programsize=0;     //用户程序的大小  
  m_pagenum=0;         //划分页面的数目
  m_pagesize=1;        //页面的大小//默认大小为1k
  failnuber=0;
  m_scout=NULL;
}

CMainClass::~CMainClass()
{

}

void CMainClass::Oninit()
{
  m_program=NULL;      //程序,划分为多个页面
  m_programsize=0;     //用户程序的大小  
  m_pagenum=0;         //划分页面的数目
  m_pagesize=1;        //页面的大小//默认大小为1k
  failnuber=0;

//初始化数据输入以KB为单位
failnuber=0;
extern int m_chengxu,m_ye;

m_pagesize=m_ye;  
m_pagesize=m_pagesize*1024;              

m_programsize=m_chengxu;                  //获得程序的大小
m_programsize=m_programsize*1024;

m_pagenum=m_programsize/m_pagesize;  //获得页面的数量

//用户程序设置
m_program=new CPage [m_pagenum+1];   //把程序划分为页的形式
  for(int i=1;i<=m_pagenum;i++)       //设置各个页的页号和偏移地址
  {
    m_program[i].m_PageNum=i;//设置页号//具有多个页号,页的多小由程序大小控制
	m_program[i].m_ExcursionAdress=(i-1)*m_pagesize;//页相对整个程序的逻辑偏移地址.
	m_program[i].m_pagesize=m_pagesize;    //设置页面大小
  }//用户程序处理完毕

//内存初始化设置
  for(i=1;i<=10;i++)
  {
	  m_memoryblock[i].m_free=true;  //内存为空闲状态
      m_memoryblock[i].m_MemoryBlockNum=i;//分配内存块标志号
	  m_memoryblock[i].m_MemoryAdress=5000+(i-1)*m_pagesize;//物理地址
      m_memoryblock[i].m_size=m_pagesize;  //设置内存块的大小
  }
//页表的初始化
  for(int j=1;j<=10;j++)
  {
   m_pagescheme[j].m_MemoryBlockNum=0;//块表初始化的时,程序没有调入内存。所以为空表
   m_pagescheme[j].m_PageNum=0;
   m_pagescheme[j].m_UsingFrequency=0;//没有被使用,命中频率当然为0了
  }
}

void CMainClass::MainFuntion()
{
   //模拟程序启动点
	
   //程序启动把第一块页面调入内存
   m_pagescheme[1].m_PageNum=m_program[1].m_PageNum;//页表与程序中的页面对应起来
   m_pagescheme[1].m_MemoryBlockNum=m_memoryblock[1].m_MemoryBlockNum;//页表中的内存块号与内存对应起来
   m_pagescheme[1].m_UsingFrequency=1;//第一条指令命中第一块页面
   m_memoryblock[1].m_free=false; //内存打上使用标志
   //读入第一条指令//指令中有4个参数 分别是: 
   //1在内存中的物理地址,2相对内存块的逻辑偏地址 3.所在内的内存块号 4所在页面的页号
   m_CurrptrDictate.m_physicsAdress=5000;          //亦是程序的始起地址
   m_CurrptrDictate.m_logicAdress=0;               //页内第一条指令,偏移地址为0
   m_CurrptrDictate.m_memoryblock=1;               //当前指令所在的内存块为第一块
   m_CurrptrDictate.m_page=1;                      //当前指令所在的页面为第一页
  //共用256条指令来测试//指令地址均为物理地址
         long pinprogram=2;//当前指令在程序中的位置
	     long ninprogram=3;//下一条指令在程序中的位置
       //  cout<<"当前指令在程序中的位置"<<pinprogram<<endl;

srand( (unsigned)time( NULL ) ); //随机种子
 extern int m_text;
//跟踪指令
 m_scout=new CDictateScout [m_text+1];


  for(int command=1;command<=m_text;command++)
  { 
     int t=0;int m_attemper;//调度情况
	 t=rand()%1000;        //产生0---1000的随机数
	 if(t<=500)            //根据题意。50%为顺序指令
	 {
         
		 ninprogram=pinprogram+1;
		 cout<<"指令由 "<<pinprogram<<"顺序执行到--->"<<ninprogram<<"\n";
         //////////////////////////////////////////////////////////////////////////////
		 //指令调度中心
	     m_attemper=Attemper(ninprogram);
		 ////////////////////////////////////////////////////////////////////////////
		 //数据跟踪系统
		   //to do add dictate scout
		   //跟踪当前指令在程序中的位置
		 m_scout[command].m_CurrptrDictateProgram=pinprogram;
		   //跟踪当前指令参数
		 m_scout[command].m_dictate.m_logicAdress=m_CurrptrDictate.m_logicAdress;
         m_scout[command].m_dictate.m_memoryblock=m_CurrptrDictate.m_memoryblock;
         m_scout[command].m_dictate.m_page=m_CurrptrDictate.m_page;
		 m_scout[command].m_dictate.m_physicsAdress=m_CurrptrDictate.m_physicsAdress;
          //跟踪下条指令在程序中的位置
		 m_scout[command].m_NextDictateProgram=ninprogram;
		  //标志当前程序状态
         m_scout[command].m_state=1;//为顺序执行
          //跟踪缺页情况
         m_scout[command].m_missState=m_attemper;
	 }//结束50%的顺序指令
	 else
	 {  	     
		 if(t<=750) //25%的指令往后跳
		 {
		   //为了防止出现第一条指令往后跳的现象,
			 if(pinprogram==1)
			 {
			 ninprogram=1;
			 }
			 else
				 ninprogram=1+rand()%(pinprogram-1);          //第一条指令到当前指令中的任意一条指令
           cout<<"指令由 "<<pinprogram<<"往后跳到--->"<<ninprogram<<"\n";
		 //////////////////////////////////////////////////////////////////////////////
		 //指令调度中心
	    m_attemper=Attemper(ninprogram);
		 ////////////////////////////////////////////////////////////////////////////
		 //数据跟踪系统
		   //to do add dictate scout
		   //跟踪当前指令在程序中的位置
		 m_scout[command].m_CurrptrDictateProgram=pinprogram;
		   //跟踪当前指令参数
		 m_scout[command].m_dictate.m_logicAdress=m_CurrptrDictate.m_logicAdress;
         m_scout[command].m_dictate.m_memoryblock=m_CurrptrDictate.m_memoryblock;
         m_scout[command].m_dictate.m_page=m_CurrptrDictate.m_page;
		 m_scout[command].m_dictate.m_physicsAdress=m_CurrptrDictate.m_physicsAdress;
          //跟踪下条指令在程序中的位置
		 m_scout[command].m_NextDictateProgram=ninprogram;
		  //标志当前程序状态
         m_scout[command].m_state=2;//为往后跳
          //跟踪缺页情况
         m_scout[command].m_missState=m_attemper;
		 }
		 else                     //25%的指令往前跳
		 {
		    if(pinprogram==m_programsize)//当前指令达到最后一条指令的时候
			{
               ninprogram=pinprogram;//指令不可以向前跳
			}
			else
		       ninprogram=pinprogram+rand()%(m_programsize-pinprogram);
		   cout<<"指令由 "<<pinprogram<<"往前跳到--->"<<ninprogram<<"\n";
          //////////////////////////////////////////////////////////////////////////////
		   //指令调度中心
		   m_attemper=Attemper(ninprogram);
		 ////////////////////////////////////////////////////////////////////////////
		 //数据跟踪系统
		   //to do add dictate scout
		   //跟踪当前指令在程序中的位置
		 m_scout[command].m_CurrptrDictateProgram=pinprogram;
		   //跟踪当前指令参数
		 m_scout[command].m_dictate.m_logicAdress=m_CurrptrDictate.m_logicAdress;
         m_scout[command].m_dictate.m_memoryblock=m_CurrptrDictate.m_memoryblock;
         m_scout[command].m_dictate.m_page=m_CurrptrDictate.m_page;
		 m_scout[command].m_dictate.m_physicsAdress=m_CurrptrDictate.m_physicsAdress;
          //跟踪下条指令在程序中的位置
		 m_scout[command].m_NextDictateProgram=ninprogram;
		  //标志当前程序状态
         m_scout[command].m_state=3;//为往前跳执行
          //跟踪缺页情况
         m_scout[command].m_missState=m_attemper;
		 }
	 }//结束指令划分
	 pinprogram=ninprogram;
     m_CurrptrDictate.m_logicAdress=m_NextDictate.m_logicAdress;
	 m_CurrptrDictate.m_memoryblock=m_NextDictate.m_memoryblock;	 
     m_CurrptrDictate.m_page=m_NextDictate.m_page;
	 m_CurrptrDictate.m_physicsAdress=m_NextDictate.m_physicsAdress;
  }//结束256条指令的测试


  // cout<<"第一条指令的物理地址"<<m_CurrptrDictate.m_physicsAdress;*/
}

void CMainClass::FifoAttemper(int m_page,long m_adress)//fifu调度算法
{
//在内存不足的情况下调用fifo算法
//调度过程中仅需要对页表进行操作
	//把第一个进来的踢走,其的元素往前走一步,最后进来的放在第十的位置
	int page,block,freque;//保存第一页表信息
    page=m_pagescheme[1].m_PageNum;
	block=m_pagescheme[1].m_MemoryBlockNum;
	freque=m_pagescheme[1].m_UsingFrequency;

	for(int i=1;i<=9;i++);
	{
		m_pagescheme[i].m_MemoryBlockNum=m_pagescheme[i+1].m_MemoryBlockNum;//后一个把前面一个覆盖//实现往前走
		m_pagescheme[i].m_PageNum=m_pagescheme[i+1].m_PageNum;
		m_pagescheme[i].m_UsingFrequency=m_pagescheme[i+1].m_UsingFrequency;
	}
   //把下一页面调进内存//采代第一页表

              //页表配置
		      m_pagescheme[10].m_PageNum=m_page;  //页面
			  m_pagescheme[10].m_MemoryBlockNum=block; //块
			  m_pagescheme[10].m_UsingFrequency=1;//
			  //内存配置
			  m_memoryblock[10].m_free=false;//打上
			  
			  //指令配置
			  m_NextDictate.m_memoryblock=block;
              m_NextDictate.m_physicsAdress=m_memoryblock[block].m_MemoryAdress+m_adress;
			  m_NextDictate.m_logicAdress=m_adress; //已经配置
			  m_NextDictate.m_page=m_page;        //已经配置
}

int CMainClass::Attemper(long DictateInProgramPosition)
{
long position=DictateInProgramPosition;

int block=-1;int page=-1;long logicadress=-1;long physicadress=-1;

//获得分页中的页号和偏移地址 
page=position/m_pagesize;
logicadress=position%m_pagesize;
  if(logicadress==0)
  {
   logicadress=m_pagesize-1;
  }
  else
  {
   page=page+1;
   logicadress=logicadress-1;
  }
		
          for(int i=1;i<=10;i++)//扫描页表找到对应的块毫
		  {
            if(page==m_pagescheme[i].m_PageNum)
			{ //当前指令在内存中//要找的它所在的内存块号
              block=m_pagescheme[i].m_MemoryBlockNum;
			  m_pagescheme[i].m_UsingFrequency++;
			  //命中
			  i=-1;//标志指令已经在内存中
			  
			  break;
			}
		 }//结束是否在内存扫描//end for

		 if(i==-1)//已经调入内存block可用
		 {  
			cout<<"命中,指令已经在内存\n";
			m_NextDictate.m_page=page;
			m_NextDictate.m_logicAdress=logicadress;
			m_NextDictate.m_memoryblock=block;//得到下条指令的所在内存块号
			m_NextDictate.m_physicsAdress=m_memoryblock[block].m_MemoryAdress+logicadress;//指令的物理地址=偏移地址+内存块的物理地址
		    return 1;
		 }
         else
		 {   
			 //页面不在内存
			 int freememoryblock=-1;
			 for(i=1;i<=10;i++)//扫描页表,看看是否有内存空闲
             {
              if(m_pagescheme[i].m_UsingFrequency==0)
			  {
			      freememoryblock=i;
				  break;
			  }
			 }//结束空闲内存扫描
			 if(freememoryblock==-1)
			 {
             //没有有空闲内存//在此进行页面置换	
			 cout<<"没有命中,所有的内存已经使用,需要进行页面置换\n";	
			 failnuber++;
			 FifoAttemper(page,logicadress);
			 return 3;
			 }
			 else
			 {
			 //有空闲内存把需要的页面调入内存//利用页表编号与内存编号对应关系有
			  //页表配置
              cout<<"没有命中,但是内存又空闲,需要把页调进内存\n";	 
			  failnuber++;
		      m_pagescheme[freememoryblock].m_PageNum=page;  //页面
			  m_pagescheme[freememoryblock].m_MemoryBlockNum=freememoryblock; //块
			  m_pagescheme[freememoryblock].m_UsingFrequency=1;//
			  //内存配置
			  m_memoryblock[freememoryblock].m_free=false;//打上
			  m_pagescheme[freememoryblock].m_UsingFrequency=1;
			  
			  //指令配置
			  m_NextDictate.m_memoryblock=freememoryblock;
              m_NextDictate.m_physicsAdress=m_memoryblock[freememoryblock].m_MemoryAdress+logicadress;
			  m_NextDictate.m_logicAdress=logicadress; //已经配置
			  m_NextDictate.m_page=page;        //已经配置
			  return 2;
			 }//结束内存是否有空判断		 
		 }//结束下条指令是否在内存判断
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -