user-0 提问: C语言页式虚存管理

回复:
user: user-1
content: #ifndef _PAGEM_H #define _PAGEM_H  #include "FIFO.h"  //enum EXISTS{NON_EXIST, EXIST}; //enum Update{Update_N, Update_Y}; typedef struct PMT{ 	unsigned char   PageID;         //页号 	unsigned char   F_EXISTS;       //是否在主存 	unsigned char   PframeID;       //页框号 	unsigned char   F_Update;       //是否修改过 	unsigned char   DiskPosition;   //磁盘位置 	struct  PMT *NEXT;             //保存下一页面地址 }pmt;    //指令 typedef struct AccQueue{ 	unsigned char   PageID;         //页号 	unsigned int    offset;         //页内偏移量 	unsigned char   F_Instruction;   //是否存指令    1:存 0:不存  -1:退出 	struct AccQueue  *next; 	unsigned char AccInfo[3];   //用于输出 	unsigned char F_interrupt;   //页面中断 }AccQue;   typedef struct{ 	node    *front; 	node    *rear; }FIFO;   pmt* SetPMT(void);  void AccessQueue(pmt **P_page, FIFO **fifo, AccQue **structaccque, AccQue **accque); void PMTInfo(pmt ** P_page);     FIFO* SetFIFO(pmt ** P_page); void Callingorder(pmt **P_page, FIFO **fifo, pmt **page); void Performance(AccQue **accque);    #endif    #include <stdio.h> #include <malloc.h> #include <stdio.h> #include <string.h> #include "PageM.h"    const unsigned char M = 3;    //主存容量 const unsigned char PageNum = 7;  //该作业页面数 const unsigned int Msize = 1024;   //  pmt* SetPMT(void) { 	pmt *P_page = (pmt *)malloc(sizeof(pmt)); 	(pmt *)memset(P_page, 0x00, sizeof(pmt)); 	P_page->NEXT = NULL; 	 	for(int i = 0; i < PageNum; ++i) 	{ 		pmt *P_npage = (pmt *)malloc(sizeof(pmt));   //建立页面 		(pmt *)memset(P_npage, 0x00, sizeof(pmt)); 		P_npage->NEXT = NULL; 		P_npage->PageID = i; 		if(i < M) 		{ 			P_npage->F_EXISTS = 1; 			P_npage->PframeID = (i | 0xA) + (i & 0xA) + ((i << 1) & 0xA) - 0X9; 		} 		else 		{ 			P_npage->F_EXISTS = 0; 			P_npage->PframeID = -1; 		} 		 		P_npage->F_Update = 0; 		P_npage->DiskPosition = (i | 0xA) + (i & 0xA) + ((i << 1) & 0xA) + ((i << 1) | 0xA); 		 		pmt *page = P_page; 		while(page->NEXT) 			page = page->NEXT; 		page->NEXT = P_npage; 		page = NULL; 	} 	 	return P_page; }  //访问 void AccessQueue(pmt **P_page, FIFO **fifo, AccQue **structaccque, AccQue **accque) { 	if(!P_page && !*P_page) 		fprintf(stderr, "P_page Error!\n"); 	if(!fifo && !*fifo) 		fprintf(stderr, "fifo Error!\n"); 	if(!structaccque && !*structaccque) 		fprintf(stderr, "structaccque Error!\n"); 	if(!accque && !*accque) 		fprintf(stderr, "accque Error!\n"); 	//遍历PMT表，查看访问页面是否在PMT表中 	pmt *pagetmp = (*P_page)->NEXT; 	unsigned char Pflag = 0;   //页面不在 	while(pagetmp) 	{ 		if(pagetmp->PageID == (*structaccque)->PageID) 		{ 			Pflag = 1; 			//存指令 			if(1 == (*structaccque)->F_Instruction)  //是否更新 				pagetmp->F_Update = 1; 			break; 		} 		pagetmp = pagetmp->NEXT; 		 	} 	if(!Pflag) 	{ 		fprintf(stderr, "\t==>>没有该页面.\n"); 		return ; 	} 	 	//访问顺序保存到AccQue; 	/*AccQue *accque = (AccQue *)malloc(sizeof(AccQue));   //连接有效访问信息 	(AccQue *)memset(accque, 0x00, sizeof(AccQue));*/ 	AccQue *acctmp = (*accque); 	while(acctmp->next) 		acctmp = acctmp->next; 	 	acctmp->next = (*structaccque); 	 	//将主存中的信息装入数组 	 	node *Pageid = (*fifo)->front; 	unsigned char i = 0; 	while(Pageid != (*fifo)->rear->next) 	{ 		(*accque)->AccInfo[i++] = Pageid->PageID; 		Pageid = Pageid->next; 	} 	if(i < 2) 		for(i; i <= 2; (*accque)->AccInfo[i++] = -1) 			; 	 	//遍历队列  没有:需要调入   有:刷新 	node *fifotmp = (*fifo)->front; 	unsigned char Fflag = 0; //不在队列中 	while(fifotmp != (*fifo)->rear->next) 	{ 		if(fifotmp->PageID == (*structaccque)->PageID) 		{ 			Fflag = 1; 			(*structaccque)->F_interrupt = 0; 			//在队列 			unsigned char i = 0; 			node *Pageidt = (*fifo)->front; 			while(Pageidt != (*fifo)->rear->next) 			{ 				(*structaccque)->AccInfo[i++] = Pageidt->PageID; 				Pageidt = Pageidt->next; 			} 			if(i < 2) 				for(i; i <= 2; (*structaccque)->AccInfo[i++] = -1) 					; 			break; 		} 		fifotmp = fifotmp->next; 	} 	 	if(!Fflag)	 //调入 	{ 		(*structaccque)->F_interrupt = 1; 		Callingorder(P_page, fifo, &pagetmp); 		node *Pageidtmp = (*fifo)->front; 		unsigned char i = 0; 		while(Pageidtmp != (*fifo)->rear->next) 		{ 			(*structaccque)->AccInfo[i++] = Pageidtmp->PageID; 			Pageidtmp = Pageidtmp->next; 		} 		if(i < 2) 			for(i; i <= 2; (*structaccque)->AccInfo[i++] = -1) 				; 	} 	else if(1 == Fflag) 	{ 		fprintf(stderr, "\t==>>页面[%d]在主存中.", (*structaccque)->PageID); 		fprintf(stderr, "\t==>>地址: %d \n.", (*structaccque)->PageID * Msize + (*structaccque)->offset); 	} 	 	return; }  void PMTInfo(pmt ** P_page) { 	if(!P_page || !*P_page) 		fprintf(stderr, "Error!"); 	 	 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	fprintf(stderr, "\t|  页号  |  标志  |  页框号  |  修改标志  |  在磁盘位置  |\n"); 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	 	pmt *pagetmp = *P_page; 	while(pagetmp->NEXT) 	{ 		pmt *page = pagetmp->NEXT;  		fprintf(stderr, "\t|   %d    |    %d   |", page->PageID, page->F_EXISTS); 		if(255 == page->PframeID) 			fprintf(stderr, "          "); 		else  			fprintf(stderr, "    %2d    ", page->PframeID); 		fprintf(stderr, "|     %d      |       %2X     |\n", page->F_Update, page->DiskPosition); 		//fprintf(stderr, "\t|--------------------------------------------------------|\n"); 		 		pagetmp = pagetmp->NEXT;    // 		page = NULL; 	} 	fprintf(stderr, "\t+--------------------------------------------------------+\n");  	 	return ; }    #ifndef _FIFO_H #define _FIFO_H  #include "PageM.h"   typedef struct Node{ 	unsigned char   PageID; //页号 	struct Node     *next; }node;    #endif    #include <stdio.h> #include <malloc.h> #include <string.h> #include "PageM.h" #include "FIFO.h"  extern const unsigned char M;  FIFO* SetFIFO(pmt ** P_page) { 	if(!P_page || !*P_page) 		fprintf(stderr, "Error!"); 	 	FIFO *fifo = (FIFO *)malloc(sizeof(FIFO)); 	(FIFO*)memset(fifo, 0x00, sizeof(FIFO)); 	fifo->front = (node *)malloc(sizeof(node)); 	(node *)memset(fifo->front, 0x00, sizeof(node)); 	fifo->front->next = NULL; 	 	fifo->rear = (node *)malloc(sizeof(node)); 	(node *)memset(fifo->rear, 0x00, sizeof(node)); 	fifo->rear = fifo->front; 	 	 	pmt *page = (*P_page)->NEXT; 	int capacity = 0; 	while(page && capacity++ < M) 	{ 		node *P_node = (node *)malloc(sizeof(node)); 		(node *)memset(P_node, 0x00, sizeof(node)); 		P_node->PageID = page->PageID; 		P_node ->next = NULL; 		 		if(1 == capacity) 			fifo->front = P_node; 		fifo->rear->next = P_node; 		fifo->rear = P_node; 		 		page = page->NEXT; 	} 	 	return fifo; }  //调入指令  void Callingorder(pmt **P_page, FIFO **fifo, pmt **page) { 	if(!page && !*page) 		fprintf(stderr, "Error!"); 	if(!fifo && !*fifo) 		fprintf(stderr, "Error!"); 	 	// 调出处理 	pmt *pagetmp = (*P_page); 	while(pagetmp->NEXT) 	{ 		if(pagetmp->NEXT->PageID == (*fifo)->front->PageID) 		{ 			pagetmp->NEXT->F_EXISTS = 0;   //设置不在主存 			if(1 == pagetmp->NEXT->F_Update) 			{ 				fprintf(stderr, "\t==>>页面[%d]的内容写回磁盘。\n", pagetmp->NEXT->PageID); 				pagetmp->NEXT->F_Update = 0; 			} 			//pagetmp->NEXT->PframeID = -1; 			fprintf(stderr, "\t==>>页面[%d]调出.\n", pagetmp->NEXT->PageID); 			break; 		} 		pagetmp = pagetmp->NEXT; 	} 	 	node *temp = (*fifo)->front;             //队首 	(*fifo)->front = (*fifo)->front->next; 	free(temp); 	 	node *P_node = (node *)malloc(sizeof(node)); 	(node *)memset(P_node, 0x00, sizeof(node)); 	P_node->PageID = (*page)->PageID; 	unsigned char i = (*page)->PageID; 	(*page)->PframeID = pagetmp->NEXT->PframeID; 	pagetmp->NEXT->PframeID = -1; 	(*page)->F_EXISTS = 1; 	P_node->next = NULL; 	 	(*fifo)->rear->next = P_node; 	(*fifo)->rear = P_node; 	 	fprintf(stderr, "\t==>>页面[%d]调入.\n", P_node->PageID); 	 	 	return ; }  //FIFO性能分析  void Performance(AccQue **accque) { 	AccQue *acctmp = (*accque)->next; 	if(!acctmp) 	{ 		fprintf(stderr, "\t==>>访问队列为空.\n"); 		return ; 	} 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	fprintf(stderr, "\t|   时刻   |"); 	unsigned char time = 1; 	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", time++); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	acctmp = (*accque)->next; 	fprintf(stderr, "\t| 页面走向 |"); 	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->PageID); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	acctmp = (*accque)->next; 	fprintf(stderr, "\t|          |"); 	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->AccInfo[2]); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	fprintf(stderr, "\t| 主存容量 |"); 	acctmp = (*accque)->next;  	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->AccInfo[1]); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	fprintf(stderr, "\t|          |"); 	acctmp = (*accque)->next;  	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->AccInfo[0]); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	unsigned char tmp = 0; 	fprintf(stderr, "\t| 缺页中断 |"); 	acctmp = (*accque)->next;  	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->F_interrupt); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	 	int rate = 0; 	acctmp = (*accque)->next; 	while(acctmp) 	{ 		if(1 == acctmp->F_interrupt) 			++rate; 		acctmp = acctmp->next; 	} 	 	fprintf(stderr, "\t 缺页率: %d / %d = %.2lf\n", rate , time-1, ((float)rate/(time-1))); 	 	return ; }