nachos 缺页置换

Lab3 只是草草的做了一下,今天上课发现确实有很多问题。还是得用虚存来实现,不过实在是懒得弄了。。


1 修改exception.cc中的方法,当发生TLB MISS时,如果该页不在内存中,从磁盘中加载该页。

else if(which == PageFaultException)
    {	//如果发生了缺页中断
	    DEBUG('p',"page fault\n");
	//获得虚拟地址
	int addr = machine->ReadRegister(BadVAddrReg);	
	//如果该页不在内存中,将硬盘中的数据拷贝到内存	
	if(!machine->LRUSwap(addr))
	{
		machine->swapPage(addr);
		//再将页表项拷贝到tlb表中
	 	machine->LRUSwap(addr);
	}
        stats->numPageFaults++;
	//DEBUG('p',"swapNum is %d\n",machine->swapNum);
     }




2. 在machine中添加属性,以用于缺页处理,从文件中读取某一页的内容到内存。
    NoffHeader noffH;		// 用来从磁盘中读取数据到内存
    OpenFile *executable;	// 打开文件

   在addrspace.cc中修改构造方法,为machine初始化属性
   //用来处理缺页置换
    machine->noffH = noffH;
    machine->executable = executable;

   在此时方法时注释掉该句,由于文件在缺页置换时还会用到,不能及时删除 
   //delete executable; // close file


3.当该页不在内存时,调用 swapPage方法,从磁盘中读取一页到内存的方法。

bool 
Machine::swapPage(int addr)
{
	
	int	vpn = addr/PageSize;
	int offset = addr%PageSize;
	int swapVpn = -1;
	int	ppn = machine->mBitmap->Find();
	int min = pageTable[0].lastUseTime;


	if(ppn==-1) //内存中没有空闲空间,利用LRU找到被置换的页
	{
		ppn = 0;
		for(int i = 0;i < pageTableSize; i++)
		{
			if(pageTable[i].lastUseTime < min && pageTable[i].valid == TRUE)
			{
				min = pageTable[i].lastUseTime;
				ppn = pageTable[i].physicalPage;
				swapVpn = i;
			}
		}	
	}
	//DEBUG('p',"ppn:%d\n",ppn);
	if(ppn == -1)
				return FALSE;
	//从硬盘中加载该页的数据
	NoffHeader noffH = machine->noffH;
	
	//int vAddr = vpn*PageSize; //该页的虚拟起始地址	 
	//DEBUG('p',"addr:%d,pAddr:%d,vAddr:%d\n",addr,pAddr,vAddr);  
	//DEBUG('p',"code.virtualAddr:%d,code.size:%d,code.inFileAddr:%d\n",
	//	noffH.code.virtualAddr,noffH.code.size,noffH.code.inFileAddr); 
	//DEBUG('p',"initData.virtualAddr:%d,initData.size:%d,initData.inFileAddr:%d\n",
	//	noffH.initData.virtualAddr,noffH.initData.size,noffH.initData.inFileAddr); 
	//DEBUG('p',"openFile:%d\n",executable->GetFileId());  	
	//判断置换页中的每一个字节是在代码段还是在数据段	
	for(int i = 0;i < PageSize;i++)
	{
		int vAddr = vpn*PageSize + i;	//要拷贝的字节的虚拟地址
		int pAddr = ppn*PageSize + i; 	//要拷贝的字节的物理地址
	   //如果在代码段
	   if(vAddr>=noffH.code.virtualAddr
		&&vAddr<(noffH.code.virtualAddr+noffH.code.size))
	   {
		machine->executable->ReadAt(&(machine->mainMemory[pAddr]),
			1,noffH.code.inFileAddr+vAddr);
	   }//如果在数据段
	   else if(addr>=noffH.initData.virtualAddr
		&&addr<(noffH.initData.virtualAddr+noffH.initData.size))
	   {
		machine->executable->ReadAt(&(machine->mainMemory[pAddr]),
			1,noffH.initData.inFileAddr+vAddr-noffH.initData.virtualAddr);
	   }
	}




	//更新pagevTable表		
	pageTable[vpn].virtualPage = vpn;
	pageTable[vpn].physicalPage = ppn;
	pageTable[vpn].valid = TRUE;
	pageTable[vpn].lastUseTime = stats->totalTicks;
	//更新被置换掉的页表项
	if(swapVpn != -1)
	{
	    pageTable[swapVpn].physicalPage = 0;
	    pageTable[swapVpn].valid = FALSE;
	    //如果被置换掉的页已经被修改
	    //写回到磁盘
	    if(pageTable[swapVpn].dirty == TRUE)
	   {
		DEBUG('p',"swap the page to disk.\n");	
	   }
	}

	return TRUE;
}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值