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

📄 sysdep.cpp

📁 LINUX 下NACHOS 系统的页面调度算法的实现
💻 CPP
字号:
// sysdep.cc//	Implementation of system-dependent interface.  Nachos uses the //	routines defined here, rather than directly calling the UNIX library,//	to simplify porting between versions of UNIX, and even to//	other systems, such as MSDOS.////	On UNIX, almost all of these routines are simple wrappers//	for the underlying UNIX system calls.////	NOTE: all of these routines refer to operations on the underlying//	host machine (e.g., the DECstation, SPARC, etc.), supporting the //	Nachos simulation code.  Nachos implements similar operations,//	(such as opening a file), but those are implemented in terms//	of hardware devices, which are simulated by calls to the underlying//	routines in the host workstation OS.////	This file includes lots of calls to C routines.  C++ requires//	us to wrap all C definitions with a "extern "C" block".// 	This prevents the internal forms of the names from being// 	changed by the C++ compiler.//// Copyright (c) 1992-1993 The Regents of the University of California.// All rights reserved.  See copyright.h for copyright notice and limitation // of liability and disclaimer of warranty provisions.#include "copyright.h"extern "C" {#include <stdio.h>#include <string.h>#include <signal.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <sys/file.h>#include <sys/un.h>#include <sys/mman.h>#ifdef HOST_i386#include <sys/time.h>#endif#ifdef HOST_SPARC#include <sys/time.h>#endif#ifdef HOST_SVR4#include <fcntl.h>#endifextern int getpagesize(void);// UNIX routines called by procedures in this file #if defined(HOST_SNAKE) || defined(HOST_SVR4)// int creat(char *name, unsigned short mode);// int open(const char *name, int flags, ...);#elseint creat(const char *name, unsigned short mode);int open(const char *name, int flags, ...);// void signal(int sig, VoidFunctionPtr func); -- this may work now!#ifdef HOST_i386int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,             struct timeval *timeout);#elseint select(int numBits, void *readFds, void *writeFds, void *exceptFds, 	struct timeval *timeout);#endif#endifint unlink(char *name);int read(int filedes, char *buf, int numBytes);int write(int filedes, char *buf, int numBytes);int lseek(int filedes, int offset, int whence);int tell(int filedes);int close(int filedes);int unlink(char *name);// definition varies slightly from platform to platform, so don't // define unless gcc complains// extern int recvfrom(int s, void *buf, int len, int flags, void *from, int *fromlen);// extern int sendto(int s, void *msg, int len, int flags, void *to, int tolen);void srand(unsigned seed);int rand(void);unsigned sleep(unsigned);void abort();//change: add int status by blueworm 2003/3/15void exit(int status);#ifndef HOST_SVR4  /* KWR added this #ifndef */int mprotect(char *addr, int len, int prot);#endif#ifndef HOST_SVR4 /* KWR may have made this #ifndef in error */int socket(int, int, int);int bind (int, const void*, int);int recvfrom (int, void*, int, int, void*, int *);int sendto (int, const void*, int, int, void*, int);#endif}#include "interrupt.h"#include "system.h"//----------------------------------------------------------------------// PollFile// 	Check open file or open socket to see if there are any //	characters that can be read immediately.  If so, read them//	in, and return TRUE.////	In the network case, if there are no threads for us to run,//	and no characters to be read,//	we need to give the other side a chance to get our host's CPU//	(otherwise, we'll go really slowly, since UNIX time-slices//	infrequently, and this would be like busy-waiting).  So we//	delay for a short fixed time, before allowing ourselves to be//	re-scheduled (sort of like a Yield, but cast in terms of UNIX).////	"fd" -- the file descriptor of the file to be polled//----------------------------------------------------------------------boolPollFile(int fd){    int rfd = (1 << fd), wfd = 0, xfd = 0, retVal;    struct timeval pollTime;// decide how long to wait if there are no characters on the file    pollTime.tv_sec = 0;    if (interrupt->getStatus() == IdleMode)        pollTime.tv_usec = 20000;              	// delay to let other nachos run    else        pollTime.tv_usec = 0;                 	// no delay// poll file or socket#if defined(HOST_i386) || defined (HOST_SVR4)    retVal = select(32, (fd_set*)&rfd, (fd_set*)&wfd, (fd_set*)&xfd, &pollTime);#else    retVal = select(32, &rfd, &wfd, &xfd, &pollTime);#endif    ASSERT((retVal == 0) || (retVal == 1));    if (retVal == 0)	return FALSE;                 		// no char waiting to be read    return TRUE;}//----------------------------------------------------------------------// OpenForWrite// 	Open a file for writing.  Create it if it doesn't exist; truncate it //	if it does already exist.  Return the file descriptor.////	"name" -- file name//----------------------------------------------------------------------intOpenForWrite(char *name){    int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0666);    ASSERT(fd >= 0);     return fd;}//----------------------------------------------------------------------// OpenForReadWrite// 	Open a file for reading or writing.//	Return the file descriptor, or error if it doesn't exist.////	"name" -- file name//----------------------------------------------------------------------intOpenForReadWrite(char *name, bool crashOnError){    int fd = open(name, O_RDWR, 0);    ASSERT(!crashOnError || fd >= 0);    return fd;}//----------------------------------------------------------------------// Read// 	Read characters from an open file.  Abort if read fails.//----------------------------------------------------------------------voidRead(int fd, char *buffer, int nBytes){    int retVal = read(fd, buffer, nBytes);    ASSERT(retVal == nBytes);}//----------------------------------------------------------------------// ReadPartial// 	Read characters from an open file, returning as many as are//	available.//----------------------------------------------------------------------intReadPartial(int fd, char *buffer, int nBytes){    return read(fd, buffer, nBytes);}//----------------------------------------------------------------------// WriteFile// 	Write characters to an open file.  Abort if write fails.//----------------------------------------------------------------------voidWriteFile(int fd, char *buffer, int nBytes){    int retVal = write(fd, buffer, nBytes);    ASSERT(retVal == nBytes);}//----------------------------------------------------------------------// Lseek// 	Change the location within an open file.  Abort on error.//----------------------------------------------------------------------void Lseek(int fd, int offset, int whence){    int retVal = lseek(fd, offset, whence);    ASSERT(retVal >= 0);}//----------------------------------------------------------------------// Tell// 	Report the current location within an open file.//----------------------------------------------------------------------int Tell(int fd){#ifdef HOST_i386    return lseek(fd,0,SEEK_CUR); // 386BSD doesn't have the tell() system call#else    return tell(fd);#endif}//----------------------------------------------------------------------// Close// 	Close a file.  Abort on error.//----------------------------------------------------------------------void Close(int fd){    int retVal = close(fd);    ASSERT(retVal >= 0); }//----------------------------------------------------------------------// Unlink// 	Delete a file.//----------------------------------------------------------------------bool Unlink(char *name){    return unlink(name);}//----------------------------------------------------------------------// OpenSocket// 	Open an interprocess communication (IPC) connection.  For now, //	just open a datagram port where other Nachos (simulating //	workstations on a network) can send messages to this Nachos.//----------------------------------------------------------------------intOpenSocket(){    int sockID;        sockID = socket(AF_UNIX, SOCK_DGRAM, 0);    ASSERT(sockID >= 0);    return sockID;}//----------------------------------------------------------------------// CloseSocket// 	Close the IPC connection. //----------------------------------------------------------------------voidCloseSocket(int sockID){    (void) close(sockID);}//----------------------------------------------------------------------// InitSocketName// 	Initialize a UNIX socket address -- magical!//----------------------------------------------------------------------static void InitSocketName(struct sockaddr_un *uname, char *name){    uname->sun_family = AF_UNIX;    strcpy(uname->sun_path, name);}//----------------------------------------------------------------------// AssignNameToSocket// 	Give a UNIX file name to the IPC port, so other instances of Nachos//	can locate the port. //----------------------------------------------------------------------voidAssignNameToSocket(char *socketName, int sockID){    struct sockaddr_un uName;    int retVal;    (void) unlink(socketName);    // in case it's still around from last time    InitSocketName(&uName, socketName);    retVal = bind(sockID, (struct sockaddr *) &uName, sizeof(uName));    ASSERT(retVal >= 0);    DEBUG('n', "Created socket %s\n", socketName);}//----------------------------------------------------------------------// DeAssignNameToSocket// 	Delete the UNIX file name we assigned to our IPC port, on cleanup.//----------------------------------------------------------------------voidDeAssignNameToSocket(char *socketName){    (void) unlink(socketName);}//----------------------------------------------------------------------// PollSocket// 	Return TRUE if there are any messages waiting to arrive on the//	IPC port.//----------------------------------------------------------------------boolPollSocket(int sockID){    return PollFile(sockID);	// on UNIX, socket ID's are just file ID's}//----------------------------------------------------------------------// ReadFromSocket// 	Read a fixed size packet off the IPC port.  Abort on error.//----------------------------------------------------------------------voidReadFromSocket(int sockID, char *buffer, int packetSize){    int retVal;    int errno;    struct sockaddr_un uName;    int size = sizeof(uName);        retVal = recvfrom(sockID, buffer, packetSize, 0,				   (struct sockaddr *) &uName, (socklen_t *)&size);    if (retVal != packetSize) {        perror("in recvfrom");        printf("called: %x, got back %d, %d\n", buffer, retVal, errno);    }    ASSERT(retVal == packetSize);}//----------------------------------------------------------------------// SendToSocket// 	Transmit a fixed size packet to another Nachos' IPC port.//	Abort on error.//----------------------------------------------------------------------voidSendToSocket(int sockID, char *buffer, int packetSize, char *toName){    struct sockaddr_un uName;    int retVal;    InitSocketName(&uName, toName);    retVal = sendto(sockID, buffer, packetSize, 0,#ifdef HOST_SVR4		    (sockaddr *) &uName,#else			  (char *) &uName,#endif		    sizeof(uName));    ASSERT(retVal == packetSize);}//----------------------------------------------------------------------// CallOnUserAbort// 	Arrange that "func" will be called when the user aborts (e.g., by//	hitting ctl-C.//----------------------------------------------------------------------void CallOnUserAbort(VoidNoArgFunctionPtr func){    (void)signal(SIGINT, (VoidFunctionPtr) func);}//----------------------------------------------------------------------// Sleep// 	Put the UNIX process running Nachos to sleep for x seconds,//	to give the user time to start up another invocation of Nachos//	in a different UNIX shell.//----------------------------------------------------------------------void Delay(int seconds){    (void) sleep((unsigned) seconds);}//----------------------------------------------------------------------// Abort// 	Quit and drop core.//----------------------------------------------------------------------void Abort(){    abort();}//----------------------------------------------------------------------// Exit// 	Quit without dropping core.//----------------------------------------------------------------------void Exit(int exitCode){    exit(exitCode);}//----------------------------------------------------------------------// RandomInit// 	Initialize the pseudo-random number generator.  We use the//	now obsolete "srand" and "rand" because they are more portable!//----------------------------------------------------------------------void RandomInit(unsigned seed){    srand(seed);}//----------------------------------------------------------------------// Random// 	Return a pseudo-random number.//----------------------------------------------------------------------int Random(){    return rand();}//----------------------------------------------------------------------// AllocBoundedArray// 	Return an array, with the two pages just before //	and after the array unmapped, to catch illegal references off//	the end of the array.  Particularly useful for catching overflow//	beyond fixed-size thread execution stacks.////	Note: Just return the useful part!////	"size" -- amount of useful space needed (in bytes)//----------------------------------------------------------------------char * AllocBoundedArray(int size){    int pgSize = getpagesize();    char *ptr = new char[pgSize * 2 + size];    mprotect(ptr, pgSize, 0);    mprotect(ptr + pgSize + size, pgSize, 0);    return ptr + pgSize;}//----------------------------------------------------------------------// DeallocBoundedArray// 	Deallocate an array of integers, unprotecting its two boundary pages.////	"ptr" -- the array to be deallocated//	"size" -- amount of useful space in the array (in bytes)//----------------------------------------------------------------------void DeallocBoundedArray(char *ptr, int size){    int pgSize = getpagesize();    mprotect(ptr - pgSize, pgSize, PROT_READ | PROT_WRITE | PROT_EXEC);    mprotect(ptr + size, pgSize, PROT_READ | PROT_WRITE | PROT_EXEC);    delete [] (ptr - pgSize);}

⌨️ 快捷键说明

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