#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include "vmm.h"
//页表
PageTableItem pageTable[PAGE_SUM];
//实存空间
BYTE actMem[ACTUAL_MEMORY_SIZE];
//用文件模拟辅存空间
FILE *ptr_auxMem;
//物理块使用标识
BOOL blockStatus[BLOCK_SUM];
//访存请求
Ptr_MemoryAccessRequest ptr_memAccReq;
//初始化环境
void do_init()
{ srand((unsigned int) time(NULL));
int i,j;
for (i = 0; i < PAGE_SUM; i++)
{ pageTable[i].filled = FALSE;
pageTable[i].edited = FALSE;
pageTable[i].count = 0;
//使用随机数设置该页的保护类型
switch (rand() % 7)
{ case 0:
{ pageTable[i].proType = READABLE;
break;
}
case 1:
{ pageTable[i].proType = WRITABLE;
break;
}
case 2:
{ pageTable[i].proType = EXECUTABLE;
break;
}
case 3:
{ pageTable[i].proType = READABLE | WRITABLE;
break;
}
case 4:
{ pageTable[i].proType = READABLE | EXECUTABLE;
break;
}
case 5:
{ pageTable[i].proType = WRITABLE | EXECUTABLE;
break;
}
case 6:
{ pageTable[i].proType = READABLE | WRITABLE | EXECUTABLE;
break;
}
default:
break;
}
//设置该页对应的辅存地址,本程序为实现简单采用顺序设置的方式,可替换成其他设置方式,但须注意每个页表项对应的辅存地址均应为PAGE_SIZE的整数倍
pageTable[i].auxAddr = i * PAGE_SIZE * 2;
}
for (j = 0; j < BLOCK_SUM; j++)
{ //随机选择一些物理块进行页面装入
if (rand() % 2 == 0)
{ do_page_in(&pageTable[j], j);
pageTable[j].blockNum = j;
pageTable[j].filled = TRUE;
blockStatus[j] = TRUE; }
else
blockStatus[j] = FALSE;
}
}
//响应请求
void do_response()
{ Ptr_PageTableItem ptr_pageTabIt;
unsigned int pageNum, offAddr;
unsigned int actAddr;
//检查地址是否越界
if (ptr_memAccReq->virAddr < 0 ||
ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
{ do_error(ERROR_OVER_BOUNDARY);
return;
}
//计算页号和页内偏移值
pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;
offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr);
//获取对应页表项
ptr_pageTabIt = &pageTable[pageNum];
//根据特征位决定是否产生缺页中断
if (!ptr_pageTabIt->filled)
{ do_page_fault(ptr_pageTabIt);
}
actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
printf("实地址为:%u\n", actAddr);
//检查页面访问权限并处理访存请求
switch (ptr_memAccReq->reqType)
{ case REQUEST_READ: //读请求
{ ptr_pageTabIt->count++;
if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
{ do_error(ERROR_READ_DENY);
return;
}
//读取实存中的内容
printf("读操作成功:值为%02X\n", actMem[actAddr]);
break;
}
case REQUEST_WRITE: //写请求
{ ptr_pageTabIt->count++;
if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
{ do_error(ERROR_WRITE_DENY);
return;
}
//向实存中写入请求的内容
actMem[actAddr] = ptr_memAccReq->value;
ptr_pageTabIt->edited = TRUE;
printf("写操作成功\n");
break;
}
case REQUEST_EXECUTE: //执行请求
{ ptr_pageTabIt->count++;
if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
{ do_error(ERROR_EXECUTE_DENY);
return;
}
printf("执行成功\n");
break;
}
default: //非法请求类型
{ do_error(ERROR_INVALID_REQUEST);
return;
}
}
}
//处理缺页中断
void do_page_fault(Ptr_PageTableItem ptr_pageTabIt)
{ printf("产生缺页中断,开始进行调页...\n");
unsigned int i;
for (i = 0; i < BLOCK_SUM; i++)
{ if (!blockStatus[i])
{ //读辅存内容,写入到实存
do_page_in(ptr_pageTabIt, i);
//更新页表内容
ptr_pageTabIt->blockNum = i;
ptr_pageTabIt->filled = TRUE;
ptr_pageTabIt->edited = FALSE;
ptr_pageTabIt->count = 0;
blockStatus[i] = TRUE;
return;
}
}
//没有空闲物理块,进行页面替换
do_LFU(ptr_pageTabIt);
}
//根据LFU算法进行页面替换
void do_LFU(Ptr_PageTableItem ptr_pageTabIt)
{ printf("没有空闲物理块,开始进行LFU页面替换...\n");
unsigned int i, min, page;
for (i = 0, min = 0xFFFFFFFF, page = 0; i < PAGE_SUM; i++)
{ if (pageTable[i].count < min)
{ min = pageTable[i].count;
page = i;
}
}
printf("选择第%u页进行替换\n", page);
if (pageTable[page].edited)
{ //页面内容有修改,需要写回至辅存
printf("该页内容有修改,写回至辅存\n");
do_page_out(&pageTable[page]);
}
pageTable[page].filled = FALSE;
pageTable[page].count = 0;
//读辅存内容,写入到实存
do_page_in(ptr_pageTabIt, pageTable[page].blockNum);
//更新页表内容
ptr_pageTabIt->blockNum = pageTable[page].blockNum;
ptr_pageTabIt->filled = TRUE;
ptr_pageTabIt->edited = FALSE;
ptr_pageTabIt->count = 0;
printf("页面替换成功\n");
}
//将辅存内容写入实存
void do_page_in(Ptr_PageTableItem ptr_pageTabIt, unsigned int blockNum)
{ unsigned int readNum;
if (fseek(ptr_auxMem, ptr_pageTabIt->auxAddr, SEEK_SET) < 0)
{ exit(1); }
if ((readNum = fread(actMem + blockNum * PAGE_SIZE, sizeof(BYTE),
PAGE_SIZE, ptr_auxMem)) < PAGE_SIZE)
{ exit(1); }
printf("调页成功:辅存地址%u-->>物理块%u\n", ptr_pageTabIt->auxAddr,
blockNum);
}
//将被替换页面的内容写回辅存
void do_page_out(Ptr_PageTableItem ptr_pageTabIt)
{ unsigned int writeNum;
if (fseek(ptr_auxMem, ptr_pageTabIt->auxAddr, SEEK_SET) < 0)
{ exit(1); }
if ((writeNum = fwrite(actMem + ptr_pageTabIt->blockNum * PAGE_SIZE,
sizeof(BYTE), PAGE_SIZE, ptr_auxMem)) < PAGE_SIZE)
{ do_error(ERROR_FILE_WRITE_FAILED);
exit(1);
}
printf("写回成功:物理块%u-->>辅存地址%u\n", ptr_pageTabIt->auxAddr,
ptr_pageTabIt->blockNum);
}
//错误处理
void do_error(ERROR_CODE code)
{ switch (code)
{ case ERROR_READ_DENY:
{ printf("访存失败:该地址内容不可读\n");
break;
}
case ERROR_WRITE_DENY:
{ printf("访存失败:该地址内容不可写\n");
break;
}
case ERROR_EXECUTE_DENY:
{ printf("访存失败:该地址内容不可执行\n");
break;
}
case ERROR_INVALID_REQUEST:
{ printf("访存失败:非法访存请求\n");
break;
}
case ERROR_OVER_BOUNDARY:
{ printf("访存失败:地址越界\n");
break;
}
case ERROR_FILE_OPEN_FAILED:
{ printf("系统错误:打开文件失败\n");
break;
}
case ERROR_FILE_CLOSE_FAILED:
{ printf("系统错误:关闭文件失败\n");
break;
}
case ERROR_FILE_SEEK_FAILED:
{ printf("系统错误:文件指针定位失败\n");
break;
}
case ERROR_FILE_READ_FAILED:
{ printf("系统错误:读取文件失败\n");
break;
}
case ERROR_FILE_WRITE_FAILED:
{ printf("系统错误:写入文件失败\n");
break;
}
default:{ printf("未知错误:没有这个错误代码\n"); }
}
}
//产生访存请求
void do_request()
{ //随机产生请求地址
ptr_memAccReq->virAddr = rand() % VIRTUAL_MEMORY_SIZE;
//随机产生请求类型
switch (rand() % 3)
{ case 0: //读请求
{ ptr_memAccReq->reqType = REQUEST_READ;
printf("产生请求:\n地址:%u\t类型:读取\n", ptr_memAccReq->virAddr);
break;
}
case 1: //写请求
{ ptr_memAccReq->reqType = REQUEST_WRITE;
//随机产生待写入的值
ptr_memAccReq->value = rand() % 0xFFu;
printf("产生请求:\n地址:%u\t类型:写入\t值:%02X\n",
ptr_memAccReq->virAddr, ptr_memAccReq->value);
break;
}
case 2:
{ ptr_memAccReq->reqType = REQUEST_EXECUTE;
printf("产生请求:\n地址:%u\t类型:执行\n", ptr_memAccReq->virAddr);
break;
}default: break;
}
}
//打印页表
void do_print_info()
{ char str[4];
printf("页号\t块号\t
vmm.rar_虚存管理
版权申诉
146 浏览量
2022-09-21
18:30:33
上传
评论
收藏 4KB RAR 举报
weixin_42653672
- 粉丝: 93
- 资源: 1万+
最新资源
- rainy-day.jpg
- IMG_20240501_171218.jpg
- Swift-内购封装swift版本
- 经典CNN网络之ResNet 图像分类网络实战项目:7种小麦叶片病害分类(迁移学习)
- Java毕设之ssm010基于ssm的新能源汽车在线租赁管理系统+vue.rar
- Java毕设之ssm009毕业生就业信息统计系统+vue.rar
- Java毕设之ssm008医院门诊挂号系统+jsp.rar
- Java毕设之ssm007亚盛汽车配件销售业绩管理统+jsp.rar
- Java毕设之ssm006基于java的少儿编程网上报名系统+vue.rar
- Java毕设之ssm005基于SSM框架的购物商城系统+jsp.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈