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

📄 mem.c

📁 solutions for some problems in Linux
💻 C
字号:
/****************************************************************************** * mem.c * This file is part of "Assignment 2: Memory Management"  * Copyright (C) 2008 - c506001 (email: c506001@cse.hcmut.edu.vn ) * * Note: * ----- * These codes are used for reference, but not complete. Students can modified * them to satisfy the requirements. *  * Content: * --------  * Functions of memory management * * System and Networking Department * Faculty of Computer Science and Engineering * Ho Chi Minh City University of Technology ******************************************************************************/#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include "sys.h"/** * findPageOnDisk: find data for faulty page on disk * @memAddr: logical address *  * @return: always 0 **/static int findPageOnDisk(int memAddr){	/* This function find a page stored on disk.	   However, we don't simulation this, so just make it a little delay. */	printf("Finding page (logical addr %d) on disk ... \n", memAddr);	sleep(1);	return 0;}/** * findFreeFrame: find a free frame in main memory * @system: system *  * @return: the free frame index or error-code (ERR_NO_FREE_FRAME) **/static int findFreeFrame(struct System *system){	int i = 0;	/* Search in system a free frame */	for (i = 0; i < system->nFrames; i++) {		if (system->frameStatus[i].state == FREE) {			printf("Frame %d is free, can be used \n", i);			return i;		}	}	printf("There is no free frames\n");
	return ERR_NO_FREE_FRAME;}/** * chooseVictimFrame: choose a victim frame by an algorithm of page replacement * @task: task * @system: system *  * @return: the victim page *  * Note: in this example, just find a victim page in task (the first VALID page) * Please read requirements to modify or rewrite this function. **/
struct PageStatus *getPageFromFrame(struct System *system, struct Task *task, int frame){
	int i = 0;
	int j = 0;
	struct PageStatus *pageStatus;

	for (i = 0; i < (1 << N_SECTION_BITS); i++) {
		for (j = 0; j < (1 << N_PAGE_BITS); j++) {
			pageStatus = getFrameFromPage(task, i, j);
			if (pageStatus->frame == frame){
				return pageStatus;
			}
		}
	}
	return NULL;
}struct PageStatus* chooseVictimFrame(struct System *system, struct Task *task){	// TODO: Implement this function with Second chance algorithm	int i = 0;//	int j = 0;	struct PageStatus *pageStatus;	/* in this algorithm of page replacement, we choose the first VALID page 	for (i = 0; i < (1 << N_SECTION_BITS); i++) {		for (j = 0; j < (1 << N_PAGE_BITS); j++) {			pageStatus = getFrameFromPage(task, i, j);			if (pageStatus->state == VALID) {				return pageStatus;			}		}	}*/
	for (i=0;i<system->nFrames;i++)	{
		if (system->frameStatus[i].lastAccessTime == 1)
			system->frameStatus[i].lastAccessTime = 0;
		else{
			pageStatus = getPageFromFrame(system, task, i);
			return pageStatus;
		}
		if (i+1 == system->nFrames)
			i = 0;printf("bi sai o dau?");
	}	return NULL;}/** * swapOutVictimPage: simulate the activities of swapping out victim page * @system: system * @pageStatus: the victim page *  * @return: always 0 **/static int swapOutVictimPage(struct System *system, 
							 struct PageStatus *pageStatus, 
							 FILE *outFile){	int frame = pageStatus->frame;	printf("swapout frame %d\n", frame);
	fprintf(outFile,"SWAPOUT %d\n",pageStatus->frame);	pageStatus->state = INVALID;	system->frameStatus[frame].state = FREE;	/* Do nothing, but it costs time. */	sleep(1);	return 0;}/**  * loadData2FreeFrame: Load data from disk to the free frame  * @system: system * @memAddr: logical address * freeFrame: the free frame *  * @return: always 0 **/ static int loadData2FreeFrame(struct System* system, int memAddr, int freeFrame, struct Task *task, FILE *outFile){	system->frameStatus[freeFrame].state = INUSE;
	system->frameStatus[freeFrame].lastAccessTime = 1;	/* Do nothing, just cost some time */	printf("Load data from disk to the free frame %d \n", freeFrame);	sleep(1);
	fprintf(outFile,"LOADTO %d %d %d\n",freeFrame, task->pid, memAddr);	return 0;}/**  * solvePageFault: routine of processing page fault. * This function is called when access to a page that is not existed in memory. * @system: system * @task: process causing page fault * @memAddr: logical memory (page fault when accessing this address) * @faultyPage: page of memAddr *  * @return: always 0 **/static int solvePageFault(struct System *system, struct Task *task,
						  int memAddr, struct PageStatus *faultyPage,
						  FILE *outFile){	int freeFrame;	struct PageStatus *victimPage = NULL;	findPageOnDisk(memAddr);	freeFrame = findFreeFrame(system);	if (freeFrame == ERR_NO_FREE_FRAME) {
		printf("\n victim page");		victimPage = chooseVictimFrame(system, task);
		printf("\n swap page");		swapOutVictimPage(system, victimPage, outFile);
		printf("\n free page");		freeFrame = victimPage->frame;	}	loadData2FreeFrame(system, memAddr, freeFrame, task, outFile);	updatePage(faultyPage, freeFrame, task->pid, memAddr, outFile);	return 0;}/** * getTask: Find a process based on pid * @system: system. * @pid: process ID. *  * @return: task or NULL **/static struct Task* getTask(struct System *system, int pid){	int i = 0;	struct TaskList *taskList = &(system->taskList);	struct Task *tmp = taskList->first;	for (i = 0; i < taskList->nTasks; i++) {		if (tmp->pid == pid) {			return tmp;		}		tmp = tmp->next;	}	return NULL;}/** * createTask: Find or Create a PCB of process * @system: system. * @pid: process ID. * @memSize: size of memory a process needs. *  * @return: task **/static struct Task* createTask(struct System *system, int pid, int memSize){	struct TaskList *taskList = &(system->taskList);	struct Task *tmp = getTask(system, pid);	/* Because task cannot be found, it will be created */	if (tmp == NULL) {		tmp = malloc(sizeof(struct Task));		initTask(tmp);		tmp->pid = pid;		tmp->memSize = memSize;		addTask2List(taskList, tmp);	}	return tmp;}/** * convertMemSize2Pages: Bytes --> pages * @system: the system that describe the framesize * @memSize: size of memory that will be converted (unit: Byte) *  * @return: a number of pages **/static int convertMemSize2Pages(struct System *system, int memSize){	int frameSize = 1 << N_OFFSET_BITS;	int pages = memSize / frameSize;	int remain = memSize % frameSize;	return (pages + (remain > 0));}/** * addFrame2PageTable: after loading data to frame, this frame will be used by  *                      the process (task) * @system: system * @task: task using this frame * @frame: frame after loading new data *  * @return: always 0 **/ int addFrame2PageTable(struct System *system, struct Task* task, int frame, FILE *outFile){	struct PageStatus *page = findUnusedPage(task);	system->frameStatus[frame].state = INUSE;
	system->frameStatus[frame].lastAccessTime = 1;	updatePage(page, frame, task->pid, task->memSize, outFile);	return 0;}/** * allocFrame4Task: called when the program does "START pid mem". *                  This task asks for allocating a memory space * @system: system * @pid: process ID * @memSize: size of memory that process pid needs (unit: Byte). * @outFile: output file *  * @return: always 0 *  * Note: In this function, a memory space is just allocated from free frames. * Please read the requirements carefully. **/int allocFrames4Task(struct System *system, int pid, int memSize, FILE *outFile){	struct Task *task;	task = createTask(system, pid, memSize);	int maxNPages = convertMemSize2Pages(system, task->memSize);	int i = 0;	int count = 0;	/* find free frames and add them to task's page table */	for (i = 0; (i < system->nFrames) && (count <= maxNPages); i++) {		if (system->frameStatus[i].state == FREE) {			addFrame2PageTable(system, task, i, outFile);
			fprintf(outFile,"ALLOC %d %d %d %d\n",pid, 0, count, i);			count++;		}	}	return 0;}/** * access2Mem: called when the process does "ACCESS pid memAddr". *             Process pid want to access a memory byte. * @system: system * @pid: process id * @memAddr: logical memory  * @outFile: output file *  * @return: frame  **/
static int releaseFrame(struct System *system, struct Task *task, FILE *outFile);
int access2Mem(struct System *system, int pid, int memAddr, 
			   FILE *outFile){	struct Task *task = getTask(system, pid);
	if (task==NULL){
		fprintf(outFile,"SEGFAULT %d\n", pid);
		releaseFrame(system, task, outFile);
		return -1;
	}	struct PageStatus *page = getFrameFromMem(task, memAddr);

	int frame = page->frame;	fprintf(outFile,"ACCESS %d\n",system->frameStatus[frame]);
	if (page->state == INVALID) {

		int section;
		int p;
		section = (memAddr >> N_OFFSET_BITS);
		p = section & ((1 << N_PAGE_BITS) - 1); // get page number
		section = (section >> N_PAGE_BITS); // get section number

		fprintf(outFile,"INVALID %d %d %d\n",pid, section, p);
		solvePageFault(system, task, memAddr, page, outFile);
		printf("Finished solve Page Fault...\n");	}
	printf("access frame: %d\n",frame);
	system->frameStatus[frame].lastAccessTime = 1;
	return (frame);}/** * releaseFrame: when finishing, all frames of process are returned to system * @system: system * @task: process *  * @return: always 0 **/static int releaseFrame(struct System *system, struct Task *task, FILE *outFile){	int i = 0;	int j = 0;	int frame = 0;	struct PageStatus *page;	for (i = 0; i < (1 << N_SECTION_BITS); i++) {		for (j = 0; j < (1 << N_PAGE_BITS); j++) {			page = getFrameFromPage(task, i, j);			if (page->state == VALID) {				frame = page->frame;
				fprintf(outFile,"FREE  %d\n", frame);				system->frameStatus[frame].state = FREE;				page->state = INVALID;			}		}	}	return 0;}/** * finishTask: called when the program does "FINISH pid 0" * @system: system * @pid: process id * @outFile: output file *  * @return: always 0 **/int finishTask(struct System *system, int pid, FILE *outFile){	struct Task *task = getTask(system, pid);	/* Release resources to system */	releaseFrame(system, task, outFile);	removeTask(&(system->taskList), task);	return 0;}

⌨️ 快捷键说明

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