nachos实验一代码

合集下载

producer

producer

实验目标在本次实验中,使用信号量,编写一段程序解决生产者/消费者同步问题。

完成本次试验,理解Nachos的信号量是如何实现的生产者/消费者问题是如何用信号量实现的在Nachos中是如何创建并发线程的在Nachos下是如何测试和debug的实验环境Linux关键源代码注释Ringring与slot的关系如图所示,在prodcons++中,定义ring的BUFF_SIZE大小为3.生产者nempty->P();查看buffer是否有空,if nempty>0,nempty=nempty -1(用nempty代替nempty.value,下nfull同).mutex->P();加锁.向ring中放入message信息.mutex->V();解锁.nfull->V();通知消费者buffer有新信息,nfull=nfull+1.关键代码如下:voidProducer(_int which){int num;slot *message = new slot(0,0);//建立slot实例,此信息message将被放到ring buffer里。

每个信息message有一个id和一个value。

//每个生产者产生的商品的个数必须使用N_MESSG限定,否则程序没有结束for (num = 0; num < N_MESSG ; num++) {message->thread_id=which; //producer的idmessage->value=num; //产生的message的编号nempty->P();mutex->P();ring->Put(message);mutex->V();nfull->V();}}消费者nfull->P();查看buffer中是否有信息,if nfull>0,nfull-1.mutex->P();加锁.从ring buffer中取出信息.mutex->V();解锁.nempty->V();通知生产者bufferr有空nempty=nempty+1.关键代码如下:voidConsumer(_int which){char str[MAXLEN];char fname[LINELEN];int fd;slot *message = new slot(0,0);// to form a output file name for this consumer thread.// all the messages received by this consumer will be recorded in // this file.sprintf(fname, "tmp_%d", which);// create a file. Note that this is a UNIX system call.if ( (fd = creat(fname, 0600) ) == -1){perror("creat: file create failed");Exit(1);}//不需要规定每个消费者消费的商品的个数for (; ; ) {nfull->P();mutex->P();ring->Get(message);mutex->V();nempty->V();// form a string to record the messagesprintf(str,"producer id --> %d; Message number --> %d;\n",message->thread_id,message->value);// write this string into the output file of this consumer.// note that this is another UNIX system call.if ( write(fd, str, strlen(str)) == -1 ) {perror("write: write failed");Exit(1);}}}生产者/消费者问题的解决mutex = new Semaphore("mutux",1);信号量初始化为1,才能起到加锁功能nfull = new Semaphore("full",0);nfull的大小在生产者没生产前为0nempty = new Semaphore("empty",BUFF_SIZE);nempty的大小应该为buffer的大小创建线程生成一个生产者的代码:producers[i] = new Thread(prod_names[i]);producers[i] -> Fork(Producer,i);关键代码如下:voidProdCons(){int i;//建立信号量mutex = new Semaphore("mutux",1);nfull = new Semaphore("full",0);nempty = new Semaphore("empty",BUFF_SIZE);// 建立ring buffer,大小为BUFF_SIZEring = new Ring(BUFF_SIZE);// 建立并唤醒N_PROD个生产者线程for (i=0; i < N_PROD; i++){sprintf(prod_names[i], "producer_%d", i);//使用prod_names[i]创建线程producers[i] = new Thread(prod_names[i]);//行为为Producer定义,i为Producer参数producers[i] -> Fork(Producer,i);};// 建立并唤醒N_CONS 个消费者线程for (i=0; i < N_CONS; i++){sprintf(cons_names[i], "consumer_%d", i);//使用cons_names[i]创建线程consumers[i] = new Thread(cons_names[i]);//定义行为为Consumer,i为Consumer参数consumers[i] -> Fork(Consumer,i);};}调试记录源代码中exit(0)没有大写,增加了许多无谓的劳动。

nachos作法

nachos作法

Nachos作法介绍Nachos(Not Another Completely Heuristic Operating System)是一个教学用的操作系统内核,由加州大学伯克利分校开发。

它是一个简化的操作系统,旨在帮助学生理解操作系统的基本原理和设计。

Nachos提供了一个模拟的计算机环境,可以在上面运行操作系统。

它提供了一些基本的系统调用,如创建进程、文件读写等,并模拟了一些硬件设备,如磁盘、内存等。

通过使用Nachos,学生可以学习操作系统的各个方面,包括进程管理、内存管理、文件系统等。

Nachos的特点Nachos有以下几个特点:1.模拟环境:Nachos提供了一个模拟的计算机环境,可以在上面运行操作系统。

这使得学生可以在不依赖真实硬件的情况下学习操作系统的原理和设计。

2.简化的操作系统:Nachos是一个简化的操作系统,它只实现了一些基本的功能,如进程管理、内存管理、文件系统等。

这使得学生可以更容易地理解和修改Nachos的代码。

3.可扩展性:Nachos的设计非常模块化,各个组件之间的耦合度较低。

这使得学生可以方便地扩展和修改Nachos的功能,以满足不同的教学需求。

4.开放源代码:Nachos是开放源代码的,任何人都可以访问和修改Nachos的代码。

这使得学生可以更深入地理解操作系统的实现细节,并参与到Nachos的开发中。

Nachos的使用方法要使用Nachos,你需要按照以下步骤进行操作:1.下载Nachos:首先,你需要从Nachos的官方网站上下载Nachos的源代码。

Nachos的官方网站提供了不同版本的Nachos,你可以根据自己的需求选择合适的版本。

2.编译Nachos:下载完Nachos的源代码后,你需要将其编译成可执行文件。

Nachos的源代码附带了一个Makefile,你只需要在终端中运行make命令即可编译Nachos。

3.运行Nachos:编译完成后,你可以在终端中运行./nachos命令来启动Nachos。

nachos实验报告

nachos实验报告

nachos实验报告nachos实验报告一、引言操作系统是计算机系统中的核心软件之一,它负责管理计算机的硬件资源和提供各种服务。

为了更好地理解操作系统的原理和设计,我们在课程中进行了一系列的实验,其中之一就是使用nachos操作系统进行实验。

本报告将对我们在nachos实验中的学习和体验进行总结和分享。

二、nachos简介nachos是一个教学用的操作系统,它是为了帮助学生更好地理解操作系统的原理和设计而开发的。

nachos的设计简单、模块化,易于理解和扩展。

通过使用nachos,我们可以深入了解操作系统的各个组成部分,如进程管理、内存管理、文件系统等,并通过实验来加深对这些概念的理解。

三、实验一:进程管理在第一个实验中,我们学习了进程管理的基本原理和实现。

通过使用nachos,我们可以创建和管理多个进程,并学习它们之间的通信和同步机制。

我们了解了进程的状态转换、进程调度算法以及进程间通信的方法,如共享内存和消息传递等。

通过实验,我们更深入地理解了进程管理的重要性和挑战。

四、实验二:内存管理在第二个实验中,我们学习了内存管理的原理和实现。

nachos提供了虚拟内存的支持,我们可以通过设置页表和实现页面置换算法来管理内存。

我们了解了内存分页和分段的概念,以及常见的页面置换算法,如FIFO、LRU等。

通过实验,我们深入了解了内存管理的工作原理和性能优化方法。

五、实验三:文件系统在第三个实验中,我们学习了文件系统的原理和实现。

nachos提供了一个简单的文件系统接口,我们可以通过创建、读取和写入文件来学习文件系统的操作。

我们了解了文件系统的组织结构,如目录、文件和索引节点等,并学习了文件系统的一致性和恢复机制。

通过实验,我们更好地理解了文件系统的工作原理和性能优化方法。

六、实验四:网络通信在第四个实验中,我们学习了网络通信的原理和实现。

nachos提供了一个简单的网络模拟器,我们可以创建和管理多个网络节点,并通过网络进行通信。

北大操作系统高级课程-陈向群作业-虚拟内存管理实习报告

北大操作系统高级课程-陈向群作业-虚拟内存管理实习报告

虚拟内存管理实习报告目录内容一:总体概述 (3)内容二:任务完成情况 (3)任务完成列表(Y/N) (3)具体Exercise的完成情况 (3)内容三:遇到的困难以及解决方法 (11)内容四:收获及感想 (11)内容五:对课程的意见和建议 (11)内容六:参考文献 (11)内容一:总体概述本次lab主要是针对操作系统内存管理的学习,内存管理主要有固定分区、可变分区、页式和段式管理。

现代操作系统主要采用页式内存管理,它把用户程序地址空间划分成大小相等的部分,称为页。

内存空间按页的大小划分为大小相等的区域,称为内存块(物理页面,页框,页帧)。

以页为单位进行分配,逻辑上相邻的页,物理上不一定相邻。

虚拟内存的基本思想:每个程序拥有自己的地址空间,这个空间被分割成多个块,每一块称作一页或者页面,每一页有连续的地址范围。

这些页被映射到物理内存,但并不是所有页都必须在内存中才能运行。

当程序引用到一部分在物理内存中的地址空间时,由硬件立即执行必要的映射。

当程序引导到一部分不在物理内存中德的地址空间时,由操作系统负责将缺失的部分装入屋里内存并重新执行失效的指令。

内容二:任务完成情况任务完成列表(Y/N)Exercise1 Exercise2 Exercise3 Exercise4 Exercise5 Exercise6 Exercise7 Challange 完成情况Y Y Y Y Y Y N N具体Exercise的完成情况一、TLB异常处理目前,Nachos系统对于内存的管理是基于软件模拟的TLB机制。

其工作原理、异常处理、替换算法等方面,与分页式内存管理非常相像。

Exercise 1 源代码阅读Ø阅读code/userprog/,着重理解nachos执行用户程序的过程,以及该过程中与内存管理相关的要点。

Ø阅读code/machine目录下的machine.h(cc),translate.h(cc)文件和code/userprog目录下的exception.h(cc),理解当前Nachos系统所采用的TLB机制和地址转换机制。

Nachos模拟操作系统的实验教学应用

Nachos模拟操作系统的实验教学应用

由于实验课 程课 时 的限制 和学生 程序实 现能 力 的差距 , 目前 国 内高校 操 作 系统 实 验 主要 以分 离 的 设计 各管 理功能 仿真 试验 为主 。各 实验 内容 之 间的
系统联 系不够 强 , 生 对各 章 节 知识 点 的理 解 不能 学
及到真正底层硬件操作代码 。其代码量也不大 , 总 共只有 8 多个文件 , 0 最大的一个源文件其代码量也
国外的操作系统教学 的以实际操作 系统 ( 例如 M — I
NX) 目的设 计 与 实 现 为 方式 的 教 学 模 式 还存 在 I 项
较 大 的差距 。
N co 没有涉及到底层的硬件操作代码, ahs 因此修改
里 面的代 码 不 会 涉 及 太 多硬 件 的 基础 。N co ahs简 单 的实现 了现代 操作 系统 的大部 分 重 要 功能 , 进 如 程管 理 , 内存 管 理 , 件 系 统 , 管 理 等 , 没 有 涉 文 I O 而
供 一个 可再生 的调 试环 境 , 能 够使 得 学 生 能 够理 也
于其代码数量较大( 超过 2万行) 且涉及较为底层 ,
的硬 件驱动 的细 节和用 户安 全 系统等 。在理论 和实 践 教学 集 中在一学 期 的课 程 而 言 , 论 对 教师 和学 无 生都有 较ቤተ መጻሕፍቲ ባይዱ 的难度 和工 作量 。
23 0
实验 与 课 程 设 计 :
N co 模拟操作 系统 的实验教 学应用 ahs
二 、hl程 序 的 扩 展 Sel
在 N co 中 Se 是一个命令解释器 , ahs hl l 它解 释
由用 户输 人 的命 令 并 且 通过 E eV或 E e 统调 xc xc系 用 来运 行 相 关 程 序 。通 常 , 验 中对 N co hl 实 ahsSel 的扩展 工作 可 以包含 以下几 个 内容 : 一是 进程 调度 ; 二 是 内存 管理 ; 是 文 件 系统 ; 三 四是 系统 调 用 ; 是 五

相关类

相关类

Thread (3/3)
• 公有方法: 公有方法: // 线程睡眠 void Sleep(bool finishing); Sleep(bool finishing); // 检查栈溢出 void CheckOverflow(); CheckOverflow(); // 打印线程名称 void Print(); Print();
Nachos关键类介 Nachos关键类介绍 关键类介绍
week08
目录
• • • Nachos进程 Nachos进程/线程相关类 进程/ Nachos内存管理相 Nachos内存管理相关类 内存管理相关类 课程实践
目录
• • • Nachos进 线程相关类 Nachos进程/线程相关类 Nachos内存管理相 Nachos内存管理相关类 内存管理相关类 课程实践
Nachos进程 线程相 Nachos进程/线程相关类(2/4) 进程/
Nachos进程 线程相 Nachos进程/线程相关类(3/4) 进程/
Nachos进程 Nachos进程/线程相关类(4/4) 进程/
• • • • Thread: 管理线程的相关数据结构 Scheduler: 调度线程的运行 Switch: 平台依赖的线程切换 Semaphore、Lock、Condition: 线程同
目录
• • • Nachos进程 线程相关类 Nachos进程/线程相关类 进程/ Nachos内存管理相关类 Nachos内存管理相关类 课程实践
Nachos内存管理相 Nachos内存管理相关类 内存管理相关类
• Translate: 虚拟地址到物理地址转换 • AddrSpace: 记录跟踪用户程序地址空间 AddrSpace:
Nachos进程 线程相 Nachos进程/线程相关类(1/4) 进程/

nachos源码分析

nachos源码分析

计算机科学与技术学院2009-2010 学年第一学期《操作系统》课程设计题目: Nachos线程模块分析班级: 070341 B 学号: 070341221 姓名:阮琳琳教师:杨志娴成绩:1. 题目分析本次课程设计中,我将遵循课本上进程部分的章节组织来分析Nachos中线程模块。

我想这样会使分析的思路更加清晰,系统性和理论性更强。

分析目的:通过阅读nachos代码,了解一个最基本的操作系统是如何工作运转起来的。

结合书本上的知识,理解nachos中的源码,并使在书本上学到的知识得到巩固。

以使我对操作一同这门课有更深入的理解。

Nachos相关知识概述一、Nachos的线程管理Nachos广泛采用线程的概念,是多线程操作系统。

线程是Nachos处理机调度的单位,在Nachos中线程分成两类,一类是系统线程。

所谓系统线程是只运行核心代码的线程,它运行在核心态下,并且占用宿主机的资源,系统线程共享Nachos操作系统本身的正文段和数据段;一个系统线程完成一件独立的任务。

Nachos的设计者认为,教授并发性的最好方法是让读者能够直观地看到程序的并发行为。

Nachos的另一类线程同Nachos中的用户进程有关。

Nachos中用户进程由两部分组成,核心代码部分和用户程序部分。

用户进程的进程控制块是线程控制块基础上的扩充。

每当系统接收到生成用户进程的请求时,首先生成一个系统线程,进程控制块中有保存线程运行现场的空间,保证线程切换时现场不会丢失。

该线程的作用是给用户程序分配虚拟机内存空间,并把用户程序的代码段和数据段装入用户地址空间,然后调用解释器解释执行用户程序;由于Nachos模拟的是一个单机环境,多个用户进程会竞争使用Nachos唯一的处理机资源,所以在Nachos用户进程的进程控制块中增加有虚拟机运行现场空间以及进程的地址空间指针等内容,保证用户进程在虚拟机上的正常运行。

系统线程竞争使用宿主机的CPU资源,而用户进程的用户程序部分竞争使用的是虚拟机的CPU和寄存器。

nachos01

nachos01

实验一体验Nachos下的并发程序设计实验简述1、在安装nachos2、实现双向链表3、线程切换的一些错误分析实验内容:1、安装nachos:首先是把nachos程序的文件code-linux.tar.gz拷贝到自己的UNIX账户下,然后将其解压,命令是tar -xzvf code-linux.tar.gz然后是测试安装有没有成功:编译,进入工作路径/nachos-3.4/code/threads执行make depend命令,这样就生成了一个名为nachos的可执行程序,运行输入命令./nachos便开始执行默认的功能(两条线程交互打印)2、实现双向链表:dllist.h 双向链表的头文件,以及里面的两个函数的声明 双向链表的具体方法的实现 调用的方法实现双向链表的有序插入和从头开始的删除里面的方法主要有两个:sortedinsert( ):实现双向链表的有序sortedremove( ):删除链表的头一个节点(first),在里面用一个for循环实现删除整个链表具体代码如下:---------------------------------------------------------------------------------------------------------------------- voiddllist::sortedinsert(void *item,int sortkey){dllelement *element=new dllelement(item,sortkey);dllelement *ptr;if(isempty()){ first=element;last=element;}else if(sortkey<first->key){element->next=first;first->prev=element;if(yield_type == 3)//线程切换点3//在first要指向新插入节点element是切换线程,导致程序错误,无法运行{ printf("switch yield_type = 3 \n");currentThread->Yield();}first=element;}else{if(yield_type == 4)//线程切换点4线程切换点4:在寻找插入点的时候(不是头节点)切换程序,导致排序错乱{printf("switch yield_type = 4 \n");currentThread->Yield();}for(ptr=first;ptr->next !=NULL;ptr=ptr->next){if(ptr->next->key>sortkey){element->prev=ptr;element->next=ptr->next;ptr->next->prev=element;ptr->next=element;return;}}last->next=element;element->prev=last;if(yield_type == 1)//线程切换点1//在last要指向新插入节点element是切换线程,导致节点丢失,{printf("switch yield_type = 1 \n");currentThread->Yield();}last=element;}}---------------------------------------------------------------------void *dllist::sortedremove(int *keyptr){ dllelement *element = first;void *thing;if (isempty())return NULL;if(keyptr != NULL)*keyptr = first->key;if(yield_type == 2)//线程切换点2//在准备删除的时候,切换程序,导致重复删除,节点删除不完全{printf("switch thread yield_type = 2 \n");currentThread->Yield();}thing = first->item;if (first == last){ // list had one item, now has nonefirst = NULL;last = NULL;}else{ element->prev=NULL;first = element->next;}delete element;return thing;}都是最基本的数据结构的知识,只是添加了一些参数进行参数线程切换里面是对上面两个函数的调用:dllist dl;char *item="abd";void dllbuild(int n,int which)//创建双向链表{//srand((unsigned)time(NULL));int i;for(int j=0;j<n;j++){i=rand()%100;dl.sortedinsert(item,i);printf("thread %d save key %d\n",which,i);}//dl.output();//printf("\n");}--------------------------------------------------------------------- void dlldeleteall(int n,int which)//删除双向链表(从头开始删){int k;for(int i=0;i<n;i++){dl.sortedremove(&k);printf("dllist thread %d delete element %dkey= %d\n",which,i,k);}}3、修改相关文件,实现多线程运行:的修改:仿造threadTest1的结构,代码如下://------------------------------------------------------------------ // set up dllist and sort\delete//----------------------------------------------------------------- voidSortAndDel(int which){ dllbuild(elenum,which);dlldeleteall(elenum,which);}//------------------------------------------------------------------ // ThreadTest2//------------------------------------------------------------------- voidThreadTest2(){ int i;DEBUG('t',"Entering ThreadTeat2");for(i=1;i<threadnum;i++){ Thread *t =new Thread("forkd dllist thread");t->Fork(SortAndDel,i);}SortAndDel(0);}voidThreadTest(){ switch (testnum) {case 1:ThreadTest1();break;case 2://双向链表ThreadTest2();break;default:printf("No test specified.\n");break;}}的修改:变量声明:extern int testnum;extern int threadnum;//线程数量extern int elenum;//双向链表节点的个数extern int yield_type;//线程切换点参数的输入:for (argc--, argv++; argc > 0; argc -= argCount, argv += argCount) { argCount = 1;switch (argv[0][1]) {case'q':testnum = atoi(argv[1]);argCount++;break;case't':threadnum = atoi(argv[1]);argCount++;break;case'n': elenum = atoi(argv[1]);argCount++;break;//双向链表节点个数case'y':yield_type= atoi(argv[1]);argCount++;break;default:testnum = 1;break;}}ThreadTest();实验结果及分析:1、修改nachos-3.4/code/mon中的THREAD_H、THREAD_C、THREAD_O:2、在nachos-3.4/code/threads/中依次执行make depend和make:4、程序执行的操作如下;-q 2 :表示运行threadTeat2( ),也就是双向链表的相关操作-t n:表示N个线程在运行-n n:表示双向链表有n个节点-y n:表示第n个线程切换点,试验中只有1、2、3、4 四个位置执行:./nachos –q 2 –t 2 –n 3 结果如下:两个线程按照顺序依次执行,结果没有错误执行:./nachos –q 2 –t 2 –n 3 –y 1 结果为:线程切换点1:在last要指向新插入节点element是切换线程,导致节点丢失,截图中可以看到,key=86的节点被覆盖掉了丢失了。

山东大学计算机学院操作系统实验报告

山东大学计算机学院操作系统实验报告

操作系统课程设计报告学院:计算机科学与技术学院专业:计算机科学与技术班级:20**级*班姓名:***学号:20**********目录一实验平台 (4)二Project1建立线程系统 (4)Task1.1实现KThread.join() (4)1.要求 (4)2.分析 (4)3.方案 (4)4.实现代码 (5)Task1.2利用中断提供原子性,直接实现条件变量 (6)1.要求 (6)2.分析 (6)3.方案 (7)4.实现代码 (7)Task1.3实现waitUntil (9)1.要求 (9)2.分析 (9)3.方案 (10)4.实现代码 (10)Task1.4用条件变量,不使用信号量,实现同步发送接收消息,speak,listen (12)1.要求 (12)2.分析 (12)3.方案 (13)4.实现代码 (13)Task1.5完成PriorityScheduler实现优先级调度 (16)1.要求 (16)2.分析 (16)3.方案 (17)4.实现代码 (17)Task1.6 (20)1.要求 (20)2.分析 (21)3.方案 (22)4.实现代码 (22)三Project2多道程序设计 (31)Task2.1 (31)1.要求 (31)2.分析 (31)3.方案 (32)4.实现代码 (35)Task2.2 (40)1.要求 (40)2.分析 (40)3.方案 (41)4.实现代码 (42)Task2.3 (48)1.要求 (48)2.分析 (49)3.方案 (49)4.实现代码 (50)Task2.4 (53)1.要求 (53)2.分析 (53)3.方案 (54)4.实现代码 (54)一实验平台开发语言:Java开发工具:Eclipse Luna操作系统:Ubuntu14.04二P roject1建立线程系统Task1.1实现KThread.join()1.要求实现Implement KThread.join()函数。

Nachos的安装和配置

Nachos的安装和配置

实验一:Nachos的安装和配置1.实验目的(1)熟悉和掌握nachos 4.1的安装与配置;(2)理解并掌握编译交叉编译工具coff2noff的生成过程和原理;(3)熟悉和理解gcc-3.4.6使得nachos可以进行编译的机制和原理。

2.实验内容(1)在ubuntu14.04中;(2)安装并编译Nachos 4.1;(3)安装并编译交叉编译工具coff2noff3.实验方法(实验步骤)第一步:安装最新版本的ncurses-dev、bison、flex和build-essential第二步:下载gcc-3.4.6,并复制到指定目录,使用dpkg工具进行安装gcc-3.4.6 第三步:安装gcc完成后,检查安装的gcc版本有哪些,当有其他版本时,将更改gcc3.4.6版本的优先级为最高级,使其替代掉原本的gcc版本。

第四步:对Nachos进行安装和编译,下载nachos 4.1的安装包,将其复制到指定目录下,然后使用tar命令解压该压缩安装包第五步:下载好的交叉编译工具包(mips-decstation. linux-xgcc.gz) 复制到根目录下并解包,然后配置并编译生成coff2noff工具第六步:当coff2noff编译错误时,根据错误信息分别进入指定目录进行符号链接的创建第七步:coff2noff配置无误后,使用make命令进行编译生成coff2noff工具第八步:coff2noff工具生成后,进入nachos test目录的配置文件Makefile.dep 第九步:使用gedit进行文件编辑时将CPP和GCCDIR进行修改第十步:根据gedit的错误进行sysdep.h文件和nachos的Makefile文件进行修改第十一步:使用make depend命令生成配置文件,make命令开始编译第十二步:安装完成后运行已经生成的nachos的可执行文件,看到线程结果即安装完成。

4.实验过程(源代码、配置清单必须带注释)1. 安装ncurses-dev:2. 安装bison:3. 安装flex:4. 安装build-essential在/mnt 下新建名为gcc-3.4.6的目录。

Nachos中文教程

Nachos中文教程

第一章绪论 (1)第一节N ACHOS概述 (1)一、引言 (1)二、Nachos教学用操作系统 (1)第二节N ACHOS的实验环境 (4)一、Nachos的安装 (4)二、Nachos的目录结构 (4)三、各个部分的编译运行 (4)四、应用程序的编译 (5)第二章机器模拟 (6)第一节概述 (6)第二节机器模拟的实现 (10)1. Sysdep模块分析(文件 sysdep.h) (10)1.1 PoolFile 函数 (10)1.2 OpenForWrite 函数 (10)1.3 OpenForReadWrite 函数 (10)1.4 Read 函数 (10)1.5 ReadPartial 函数 (11)1.6 WriteFile 函数 (11)1.7 Lseek 函数 (11)1.8 Tell 函数 (11)1.9 Close 函数 (11)1.10 Unlink 函数 (12)1.11 OpenSocket 函数 (12)1.12 CloseSocket 函数 (12)1.13 AssignNameToSocket 函数 (12)1.14 DeAssignNameToSocket 函数 (12)1.15 PoolSocket 函数 (12)1.16 ReadFromSocket 函数 (13)1.17 SendToSocket 函数 (13)1.18 CallOnUserAbort 函数 (13)1.19 Delay 函数 (13)1.20 Abort 函数 (13)1.21 Exit 函数 (14)1.22 RandomInit 函数 (14)1.23 Random 函数 (14)1.24 AllocBoundedArray 函数 (14)1.25 DeallocBoundedArray 函数 (14)2. 中断模块分析(文件 interrupt.h) (14)2.1 PendingInterrupt类 (16)2.2 Interrupt类 (17)2.2.1 内部使用方法 (17)2.2.2 内部使用函数 (18)2.2.3 对外接口 (18)3. 时钟中断模块分析(文件 timer.h) (20)4. 终端设备模块分析(文件 console.h) (22)5. 磁盘设备模块分析(文件 disk.h) (23)6. Nachos运行情况统计(文件 stats.h) (24)第三章线程管理系统 (25)第一节进程与线程 (25)一、进程 (25)1. 进程概念 (25)2. 进程的状态及状态变化 (25)3. 进程调度 (26)4. 进程之间的同步和互斥 (27)5. 进程的实施 (28)6. 进程的创建 (28)二、线程 (28)1. 线程概念 (28)2. 进程和线程的关系 (30)第二节N ACHOS的线程管理 (31)一、Nachos的线程管理 (31)二、Nachos线程管理同实际进程管理的不同 (33)第三节N ACHOS线程管理系统的初步实现 (34)1. 工具模块分析(文件 list.h utility.h) (34)2. 线程启动和调度模块分析(文件switch.s switch.h) (34)2.1 ThreadRoot函数 (34)2.2 SWITCH函数 (35)3. 线程模块分析(文件 thread.h) (35)3.1 Fork 方法 (37)3.2 StackAllocate 方法 (37)3.3 Yield 方法 (38)3.4 Sleep 方法 (39)4. 线程调度算法模块分析(文件 scheduler.h) (39)4.1 Run方法 (40)5. Nachos主控模块分析(文件 system.h) (40)6. 同步机制模块分析(文件 synch.h) (41)6.1 信号量( Semaphore ) (41)6.2 锁机制 (41)6.3 条件变量 (42)第四节线程管理系统作业 (44)第五节实现实例 (46)4.1 对线程的改进 (46)4.2 对线程调度的改进 (47)第四章文件管理系统 (50)第一节文件管理系统概述 (50)一、文件 (50)1. 文件结构 (50)2. 文件访问 (51)3. 文件类型 (51)4. 文件属性 (52)5. 文件操作 (52)二、目录 (53)1. 目录结构 (53)2. 多级目录结构 (54)3. 文件路径名 (54)4. 工作目录 (54)5. 目录结构的勾连 (54)6. 目录项 (55)三、UNIX文件系统的实现 (55)1. UNIX文件系统中的主要结构 (55)2. UNIX文件系统存储资源的分配和回收 (57)第二节N ACHOS文件管理系统 (60)第三节N ACHOS文件系统的实现 (62)1. 同步磁盘分析(文件 、synchdisk.h) (62)2. 位图模块分析(文件、bitmap.h) (63)3. 文件系统模块分析(文件、filesys.h) (63)3.1 生成方法 (64)3.2 Create方法 (64)3.3 Open方法 (65)3.4 Remove方法 (65)4. 文件头模块分析(文件、filehdr.h) (65)5. 打开文件结构分析(文件、openfile.h) (66)5.1 ReadAt方法 (66)5.2 WriteAt方法 (66)6. 目录模块分析(文件 directory.h) (67)第四节文件管理系统作业 (69)第五章用户程序和虚拟内存 (70)第一节N ACHOS 对内存、寄存器以及CPU的模拟 (70)1 RaiseException 方法 (73)2 ReadMem 方法 (73)3 WriteMem 方法 (73)4 Translate方法 (73)5 Run 方法 (74)第二节N ACHOS用户进程运行机制 (75)一、用户程序空间(文件, address.h) (75)1.1 生成方法 (75)1.2 InitRegisters方法 (76)1.3 SaveState方法 (76)1.4 RestoreState方法 (76)二、系统调用(文件, syscall.h, start.s) (76)第三节虚存管理的设计和实现 (78)一、Nachos存储管理的改进要求 (78)二、一个虚拟存储管理实现的实例 (78)2.1 虚拟存储系统的总体设计 (78)2.2 缺页中断陷入及其调度算法 (81)2.3 虚存的存储分配 (83)2.4 存储保护 (83)2.5 实现中的一些细节 (83)第四节用户程序和虚拟存储作业 (85)第六章NACHOS的网络系统 (86)第一节N ACHOS对物理网络的模拟 (86)第二节N ACHOS的邮局协议 (89)2.1 PostalDelivery方法 (90)2.2 Send方法 (91)第三节网络部分作业 (92)第一章绪论第一节Nachos概述一、引言计算机操作系统是一门实践性很强的课程。

nachos Lab4实习报告

nachos Lab4实习报告

虚拟内存实习报告目录内容一:总体概述 (3)内容二:任务完成情况 (3)任务完成列表(Y/N) (3)具体Exercise的完成情况 (3)内容三:遇到的困难以及解决方法 (23)内容四:收获及感想 (24)内容五:对课程的意见和建议 (24)内容六:参考文献 (24)内容一:总体概述实习的主要内容是了解和改进nachos存储管理相关实现,主要分为三个部分。

第一部分的主要内容是实现TLB相关异常处理和置换算法,第二部分的主要内容是实现全局内存管理机制,使得nachos内存可以同时存在复数线程,第三部分的主要内容是实现程序运行时载入所需页面。

扩展部分主要是增加线程挂起状态以及实现倒排页表。

内容二:任务完成情况任务完成列表(Y/N)Exercise1 Exercise2 Exercise3 Exercise4 Exercise5 Exercise6 Exercise7 Y Y Y Y Y Y Y Challenge1 Challenge2Y Y具体Exercise的完成情况一、TLB异常处理目前,Nachos系统对于内存的管理是基于软件模拟的TLB机制。

其工作原理、异常处理、替换算法等方面,与分页式内存管理非常相像。

Exercise1 源代码阅读阅读code/userprog/,着重理解nachos执行用户程序的过程,以及该过程中与内存管理相关的要点。

阅读code/machine目录下的machine.h(cc),translate.h(cc)文件和code/userprog目录下的exception.h(cc),理解当前Nachos系统所采用的TLB 机制和地址转换机制(1)用户程序执行过程userprog/定义函数StartProcess主要功能是实现用户程序启动,如果我们希望执行test中的用户程序,那么我们进入userprog,执行./nachos -x ../test/(用户程序),通过识别-x参数,nachos调用StartProcess执行用户程序(具体实现在threads/)StartProcess的基本流程是,通过文件系统定义的OpenFile打开相关文件,通过AddrSpace的构造函数建立用户空间,装载文件,通过AddrSpace的InitRegisters函数初始化用户寄存器,通过AddrSpace的RestoreState函数装载页表,通过machine的Run函数运行用户程序AddrSpace的构造函数实现在userprog/,主要流程是,获取文件头,大小端做适宜转换,通过文件头计算文件所需空间,包括代码段,初始化数据段,未初始化数据段,栈空间4个部分,通过文件所需空间计算出文件所需的虚拟页面数量,创建用户空间页表,指示了第i个虚拟页对应第i个物理页,将用户程序的正文段和相关数据依次调入内存AddrSpace的InitRegisters函数实现在userprog/,主要流程是初始化普通寄存器(初始化为0),初始化当前指令指针(PC,初始化为0),初始化下一条指令指针(初始化为4),初始化栈指针(地址空间尾部适当前移)AddrSpace的RestoreState函数实现在userprog/,主要流程是将页表装载到machine类中,准备执行用户程序machine的Run函数实现在machine/,基本流程是通过OneInstruction函数完成指令译码和执行,通过interrupt的OneTick函数使得时钟前进machine的Run函数通过machine的ReadMem函数读内存数据,通过machine 的WriteMem函数写内存数据,两个函数的实现在machine/,核心是translate函数,translate函数实现在machine/,主要功能是实现虚拟地址到物理地址的转换,translate函数可能返回相应的错误,在这样的情况下,ReadMem函数/WriteMem函数调用RaiseException函数进行处理,RaiseException函数定义在machine/,基本流程是将错误信息存储在特定位置,调用ExceptionHandler函数处理不同的错误,ExceptionHandler 函数实现在userprog/,主要流程是根据错误信息处理不同错误。

Nachos的shell实现

Nachos的shell实现

四川大学计算机学院、软件学院
实验报告
学号:___________ 姓名:____专业:______
班级:____第周
出为止。

的实现:
实验报告说明
专业实验中心
实验名称要用最简练的语言反映实验的内容。

如验证某程序、定律、算法,可写成“验证×××”;分析×××。

实验目的目的要明确,要抓住重点,可以从理论和实践两个方面考虑。

在理论上,验证定理、公式、算法,并使实验者获得深刻和系统的理解,在实践上,掌握使用实验设备的技能技巧和程序的调试方法。

一般需说明是验证型实验还是设计型实验,是创新型实验还是综合型实验。

实验环境实验用的软硬件环境(配置)。

实验内容(算法、程序、步骤和方法)这是实验报告极其重要的内容。

这部分要写明依据何种原理、定律算法、或操作方法进行实验,要写明经过哪几个步骤。

还应该画出流程图(实验装置的结构示意图),再配以相应的文字说明,这样既可以节省许多文字说明,又能使实验报告简明扼要,清楚明白。

数据记录和计算指从实验中测出的数据以及计算结果。

结论(结果)即根据实验过程中所见到的现象和测得的数据,作出结论。

小结对本次实验的体会、思考和建议。

备注或说明可写上实验成功或失败的原因,实验后的心得体会、建议等。

注意:
∙实验报告将记入实验成绩;
∙每次实验开始时,交上一次的实验报告,否则将扣除此次实验成绩。

操作系统实验报告一

操作系统实验报告一

实验报告课程名称:操作系统(nachos)Array实验项目名称:进程调度实验时间:2010-09-08班级:姓名:学号:实验目的:用高级语言编写和调试一个有 N个进程并行的进程调度程序,以加深对进程的概念及进程调度算法的理解。

实验环境:PC机、windows XP 操作系统、Visual C++6.0开发工具/Win-TC实验内容及过程:实验内容:设计一个有N个进程并行的进程调度程序。

进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。

具体描述如下:每个进程有一个进程控制块( PCB)表示。

进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。

分析:进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。

进程的到达时间为进程输入的时间。

进程的运行时间以时间片为单位进行计算。

每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

就绪进程获得 CPU后都只能运行一个时间片。

用已占用CPU时间加1来表示。

如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后按照优先数的大小把它插入就绪队列等待CPU。

每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。

重复以上过程,直到所要进程都完成为止。

调度算法的参考流程图如下:实验过程:1.在win-tc环境中编写一个有N个进程并行的进程调度程序,包括最高优先数优先的调度算法和先来先服务算法,代码见附录中。

2.在上机环境中编译、调试程序。

3.设计输入数据,得出程序的执行结果。

实验结果及分析:1、选择最高优先数优先的调度算法调度两个进程:输出进程名、进程cpu时间、进程还需时间、进程优先数及进程状态,最高优先数优先的调度算法调度三个进程:2、选择先来先服务算法调度两个进程:输出进程名、进程开始时间及结束时间,先来先服务算法调度三个进程:实验心得:操作系统第一份实验刚开始确实有点没头绪,而且也刚接触一点儿进程调度的,对它只是大概了解些。

NachOS实验报告(4个全)

NachOS实验报告(4个全)

NachOS实验报告(4个全)四川大学操作系统课程设计报告学院:软件学院专业:软件工程专业年级:08级组编号:组成员:提交时间:2010年6月24日指导教师评阅意见:.. . . .指导教师评阅成绩:::实验项目一项目名称:开发Shell程序试验背景知识Shell此处的shell是指命令行式的shell。

文字操作系统与外部最主要的接口就叫做shell。

shell是操作系统最外面的一层。

shell管理你与操作系统之间的交互:等待你输入,向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果。

shell提供了你与操作系统之间通讯的方式。

这种通讯可以以交互方式(从键盘输入,并且可以立即得到响应),或者以shell script(非交互)方式执行。

shell script是放在文件中的一串shell和操作系统命令,它们可以被重复使用。

本质上,shell script是命令行命令简单的组合到一个文件里面。

Shell基本上是一个命令解释器,类似于DOS下的。

它接收用户命令(如ls等),然后调用相应的应用程序。

较为通用的shell有标准的Bourne shell (sh)和C shell (csh)。

交互式shell和非交互式shell交互式模式就是shell等待你的输入,并且执行你提交的命令。

这种模式被称作交互式是因为shell与用户进行交互。

这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。

当你签退后,shell 也终止了。

shell也可以运行在另外一种模式:非交互式模式。

在这种模式下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。

当它读到文件的结尾,shell也就终止了。

实验目的:Shell是一个命令处理器(command processor)——是一个读入并解释你输入的命令的程序,它是介于使用者和操作系统之核心程序(kernel)间的一个接口。

它是一个交互性命令解释器。

操作系统课程设计-管程的实现(生产者消费者问题)

操作系统课程设计-管程的实现(生产者消费者问题)

操作系统课程设计2、管程的实现(生产者消费者问题)1.设计背景:管程是一种高级抽象数据类型,它支持在它的函数中隐含互斥操作。

结合条件变量和其他一些低级通信原语,管程可以解决许多仅用低级原语不能解决的同步问题。

例如,本实验中利用管程提供一个不会发生死锁的生产者消费者问题就是利用管程的很好的例子。

管程封装了并发进程或线程要互斥执行的函数。

为了让这些并发进程或线程在管程内互斥的执行,管程的实现必须隐含的具有锁或二值信号量。

如果没有条件变量,管程就不会有很有用,条件变量提供了一种对管程内并发协作进程的同步机制。

条件变量代表了管程中一些并发进程或线程可能要等待的条件。

一个条件变量管理着管程内的一个等待队列。

如果管程内某个进程或线程发现其执行条件为假,则该进程或线程就会被条件变量挂入管程内等待该条件的队列。

如果管程内另外的进程或线程满足了这个条件,则它会通过条件变量再次唤醒等待该条件的进程或线程,从而避免了死锁的产生。

所以,一个条件变量C应具有两种操作 C.wait()和C.signal()。

当管程内同时出现唤醒者和被唤醒者时,由于要求管程内的进程或线程必须互斥执行,因此就出现了两种样式的条件变量:Mesa Style(signal-and-continue): 唤醒者进程或线程继续执行,被唤醒者进程或线程等到唤醒者进程或线程阻塞或离开管程后再执行。

Hoare Style(signal-and-wait): 被唤醒者进程或线程立即执行,唤醒者进程或线程阻塞,直道被唤醒者阻塞或离开管程后再执行。

我们实验所做的就是在原来mesa样式的基础上进行Hoare样式的改进;这种样式也是我们实验中需要实现的样式。

2.设计目标验证并分析Nachos中Bridge管程是否能够正确的解决单行桥双向过桥问题。

定义和实现Hoare样式的条件变量Condition_H类利用Hoare样式的条件变量Condition_H,实现Ring类中定义的各个方法,使用Ring管程解决生产者/消费者问题。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Test文件下:shell.c:#include "syscall.h"intmain(){SpaceId newProc;OpenFileId input = ConsoleInput;OpenFileId output = ConsoleOutput;char ch, buffer[60];int i;Write( "\t\t<-ZhangCJ's shell welcome you->\n", 34, output);while( 1 ){Write( "<-Please Input-> :", 20, output);i = 0;do {Read(&buffer[i], 1, input);} while( buffer[i++] != '\n' );buffer[--i] = '\0';if(Strncmp(buffer,"exit",4)==0){Halt();}if( i > 0 ) {newProc = Exec(buffer);Join(newProc);}}}Start.s :/* Start.s* Assembly language assist for user programs running on top of Nachos. ** Since we don't want to pull in the entire C library, we define* what we need for a user program here, namely Start and the system* calls.*/#define IN_ASM#include "syscall.h".text.align 2/* -------------------------------------------------------------* __start* Initialize running a C program, by calling "main".** NOTE: This has to be first, so that it gets loaded at location 0.* The Nachos kernel always starts a program by jumping to location 0. * -------------------------------------------------------------*/.globl __start.ent __start__start:jal mainmove $4,$0jal Exit /* if we return from main, exit(0) */.end __start/* -------------------------------------------------------------* System call stubs:* Assembly language assist to make system calls to the Nachos kernel. * There is one stub per system call, that places the code for the* system call into register r2, and leaves the arguments to the* system call alone (in other words, arg1 is in r4, arg2 is* in r5, arg3 is in r6, arg4 is in r7)** The return value is in r2. This follows the standard C calling* convention on the MIPS.* -------------------------------------------------------------.globl Halt.ent HaltHalt:addiu $2,$0,SC_Haltsyscallj $31.end Halt.globl Add.ent AddAdd:addiu $2,$0,SC_Addsyscallj $31.end Add.globl Exit.ent ExitExit:addiu $2,$0,SC_Exitsyscallj $31.end Exit.globl Exec.ent ExecExec:addiu $2,$0,SC_Execsyscallj $31.end Exec.globl ExecV.ent ExecVExecV:addiu $2,$0,SC_ExecVsyscallj $31.end ExecV.globl Join.ent Joinaddiu $2,$0,SC_Joinsyscallj $31.end Join.globl Create.ent CreateCreate:addiu $2,$0,SC_Createsyscallj $31.end Create.globl Remove.ent Remove Remove:addiu $2,$0,SC_Removesyscallj $31.end Remove.globl Open.ent OpenOpen:addiu $2,$0,SC_Opensyscallj $31.end Open.globl Read.ent ReadRead:addiu $2,$0,SC_Readsyscallj $31.end Read.globl Write.ent WriteWrite:addiu $2,$0,SC_Writesyscallj $31.end Write.globl Close.ent CloseClose:addiu $2,$0,SC_Closesyscallj $31.end Close.globl Seek.ent SeekSeek:addiu $2,$0,SC_Seeksyscallj $31.end Seek.globl Delete.ent DeleteDelete:addiu $2,$0,SC_Deletesyscallj $31.end Delete.globl ThreadFork.ent ThreadFork ThreadFork:addiu $2,$0,SC_ThreadForksyscallj $31.end ThreadFork.globl ThreadYield.ent ThreadYield ThreadYield:addiu $2,$0,SC_ThreadYieldsyscallj $31.end ThreadYield.globl ThreadExit.ent ThreadExitThreadExit:addiu $2, $0, SC_ThreadExitsyscallj $31.end ThreadExit.globl ThreadJoin.ent ThreadJoin ThreadJoin:addiu $2, $0, SC_ThreadJoinsyscallj $31.end ThreadJoin.globl getSpaceID.ent getSpaceID getSpaceID:addiu $2,$0,SC_getSpaceIDsyscallj $31.end getSpaceID.globl getThreadID.ent getThreadID getThreadID:addiu $2,$0,SC_getThreadIDsyscallj $31.end getThreadID.globl Ipc.ent IpcIpc:addiu $2,$0,SC_Ipcsyscallj $31.end Ipc.globl Clock.ent ClockClock:addiu $2,$0,SC_Clocksyscallj $31.end Clock/* dummy function to keep gcc happy */.globl __main.ent __main__main:j $31.end __main.globl Strncmp.ent StrncmpStrncmp:addiu $2,$0,SC_Strncmpsyscallj $31.end Strncmp.globl Exit.ent ExitUserprog文件夹下:// // Entry point into the Nachos kernel from user programs.// There are two kinds of things that can cause control to// transfer back to here from user code://// syscall -- The user code explicitly requests to call a procedure// in the Nachos kernel. Right now, the only function we support is// "Halt".//// exceptions -- The user code does something that the CPU can't handle. // For instance, accessing memory that doesn't exist, arithmetic errors, // etc.//// Interrupts (which can also cause control to transfer from user// code into the Nachos kernel) are handled elsewhere.//// For now, this only handles the Halt() system call.// Everything else core dumps.// Copyright (c) 1992-1996 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"#include "main.h"#include "syscall.h"#include "ksyscall.h"//----------------------------------------------------------------------// ExceptionHandler// Entry point into the Nachos kernel. Called when a user program// is executing, and either does a syscall, or generates an addressing// or arithmetic exception.//// For system calls, the following is the calling convention://// system call code -- r2// arg1 -- r4// arg2 -- r5// arg3 -- r6// arg4 -- r7//// The result of the system call, if any, must be put back into r2.//// If you are handling a system call, don't forget to increment the pc// before returning. (Or else you'll loop making the same system call forever!)//// "which" is the kind of exception. The list of possible exceptions// is in machine.h.//----------------------------------------------------------------------voidExceptionHandler(ExceptionType which){int type = kernel->machine->ReadRegister(2);DEBUG(dbgSys, "Received Exception " << which << " type: " << type << "\n");switch (which) {case SyscallException:switch(type) {case SC_Halt:DEBUG(dbgSys, "Shutdown, initiated by user program.\n");SysHalt();ASSERTNOTREACHED();break;case SC_Write:DEBUG(dbgSys,"Write from buffer to consoleOutput"<<kernel->machine->ReadRegister(4)<<kernel->machine->ReadRegister(5)<<kernel->machine->ReadRegister(6)<<"\n");char wbuffer[60];int size ;size=(int)kernel->machine->ReadRegister(5);OpenFileId printOut;printOut= (OpenFileId)kernel->machine->ReadRegister(6);int addressOne;addressOne=(int)kernel->machine->ReadRegister(4);int i;i=0;do{kernel->machine->ReadMem(addressOne++,1,(int*)&wbuffer[i++]); }while(i<size);int n1;n1=SysWrite((char*)wbuffer,size,printOut);kernel->machine->WriteRegister(2,n1);{kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg));kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4);kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);} return;ASSERTNOTREACHED();break;case SC_Read:DEBUG(dbgSys, "read from buffer" << kernel->machine->ReadRegister(4) << kernel->machine->ReadRegister(5)<< kernel->machine->ReadRegister(6) << "\n");int rsize ;rsize=(int)kernel->machine->ReadRegister(5);OpenFileId enterIn;enterIn = (OpenFileId)kernel->machine->ReadRegister(6);char addressTwo;addressTwo = (char)kernel->machine->ReadRegister(4);int local ;local= (int)kernel->machine->ReadRegister(4);;int n2 ;n2= SysRead(&addressTwo,rsize,enterIn);kernel->machine->WriteMem(local,1,(int)addressTwo);kernel->machine->WriteRegister(2,n2);{kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg));kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4); kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);}return;ASSERTNOTREACHED();break;case SC_Exec:DEBUG(dbgSys,"execute a command"<<kernel->machine->ReadRegister(4)<<"\n"); char ebuffer[60];int addressThree;addressThree = kernel->machine->ReadRegister(4);int c;c = 0;do{kernel->machine->ReadMem(addressThree++,1,(int*)&ebuffer[c++]); }while(c<60); kernel->machine->WriteRegister(2,SysExec(ebuffer));{kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg));kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4); kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);}return;ASSERTNOTREACHED();break;case SC_Join:DEBUG(dbgSys,"jion "<<kernel->machine->ReadRegister(4)<<"\n");kernel->machine->WriteRegister(2,SysJoin((SpaceId)kernel->machine->ReadRegister(4))); {kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg));kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4);kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);}return;ASSERTNOTREACHED();break;case SC_Strncmp:DEBUG(dbgSys, "compare two string " << kernel->machine->ReadRegister(4) <<kernel->machine->ReadRegister(5) << kernel->machine->ReadRegister(6) << "\n");int addressFour;addressFour = kernel->machine->ReadRegister(4);int addressFive;addressFive = kernel->machine->ReadRegister(5);char str1buffer[60];char str2buffer[60];int d,e;d= 0;e=0;do{kernel->machine->ReadMem(addressFour++,1,(int*)&str1buffer[d++]); }while(d<60);--addressFour;do{ kernel->machine->ReadMem(addressFive++,1,(int*)&str2buffer[e++]);}while(e<60);--addressFive;int n3;n3=SysStrncmp(str1buffer,str2buffer,kernel->machine->ReadRegister(6));kernel->machine->WriteRegister(2,n3);{kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg));kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4); kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);}return;ASSERTNOTREACHED();break;case SC_Add:DEBUG(dbgSys, "Add " << kernel->machine->ReadRegister(4) << " + " << kernel->machine->ReadRegister(5) << "\n");/* Process SysAdd Systemcall*/int result;result = SysAdd(/* int op1 */(int)kernel->machine->ReadRegister(4),/* int op2 */(int)kernel->machine->ReadRegister(5));DEBUG(dbgSys, "Add returning with " << result << "\n");/* Prepare Result */kernel->machine->WriteRegister(2, (int)result);/* Modify return point */{/* set previous programm counter (debugging only)*/kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));/* set programm counter to next instruction (all Instructions are 4 byte wide)*/kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);/* set next programm counter for brach execution */kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);}return;ASSERTNOTREACHED();break;default:cerr << "Unexpected system call " << type << "\n";break;}break;default:cerr << "Unexpected user mode exception" << (int)which << "\n";break;}ASSERTNOTREACHED();}Ksyscall.h :/************************************************************** ** userprog/ksyscall.h** Kernel interface for systemcalls** by Marcus Voelp (c) Universitaet Karlsruhe***************************************************************/#ifndef __USERPROG_KSYSCALL_H__#define __USERPROG_KSYSCALL_H__#include "kernel.h"#include <stdlib.h>#include <string.h>#include <sys/time.h>#include <sys/file.h>#include <stdarg.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/wait.h>#include <sched.h>#include <signal.h>#include <sys/types.h>#include <pthread.h>#define SHELL "/bin/sh"int SysWrite(char*buffer ,int size,OpenFileId id) {return write(id,buffer,(size_t)size);}int SysRead(char*buffer ,int size,OpenFileId id) {return read(id, buffer, (size_t)size);}SpaceId SysExec(char* exec_name){pid_t child;child = vfork();if(child == 0){execl (SHELL, SHELL, "-c", exec_name, NULL); _exit (EXIT_FAILURE);}else if(child < 0)return EPERM;return (SpaceId) child;}int SysJoin(SpaceId id){return waitpid((pid_t)id, (int*)0, 0);}int SysStrncmp(char*buffer,char *str,int n) {return strncmp(buffer,str,(size_t)n);}void SysHalt(){kernel->interrupt->Halt();}int SysAdd(int op1, int op2){return op1 + op2;}#endif /* ! __USERPROG_KSYSCALL_H__ */Syscall.h:/* syscalls.h* Nachos system call interface. These are Nachos kernel operations* that can be invoked from user programs, by trapping to the kernel* via the "syscall" instruction.** This file is included by user programs and by the Nachos kernel.** 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.*/#ifndef SYSCALLS_H#define SYSCALLS_H#include "copyright.h"#include "errno.h"/* system call codes -- used by the stubs to tell the kernel which system call * is being asked for*/#define SC_Halt 0#define SC_Exit 1#define SC_Exec 2#define SC_Join 3#define SC_Create 4#define SC_Remove 5#define SC_Open 6#define SC_Read 7#define SC_Write 8#define SC_Seek 9#define SC_Close 10#define SC_Delete 11#define SC_ThreadFork 12#define SC_ThreadYield 13#define SC_ExecV 14#define SC_ThreadExit 15#define SC_ThreadJoin 16#define SC_getSpaceID 17#define SC_getThreadID 18#define SC_Ipc 19#define SC_Clock 20#define SC_Add 42#define SC_Strncmp 43#ifndef IN_ASM/* The system call interface. These are the operations the Nachos* kernel needs to support, to be able to run user programs.** Each of these is invoked by a user program by simply calling the* procedure; an assembly language stub stuffs the system call code* into a register, and traps to the kernel. The kernel procedures* are then invoked in the Nachos kernel, after appropriate error checking, * from the system call entry point in .*//* Stop Nachos, and print out performance stats */void Halt();int Strncmp(char *buffer,char*str,int size);/** Add the two operants and return the result*/int Add(int op1, int op2);/* Address space control operations: Exit, Exec, Execv, and Join *//* This user program is done (status = 0 means exited normally). */ void Exit(int status);/* A unique identifier for an executing user program (address space) */ typedef int SpaceId;/* A unique identifier for a thread within a task */typedef int ThreadId;/* Run the specified executable, with no args *//* This can be implemented as a call to ExecV.*/SpaceId Exec(char* exec_name);/* Run the executable, stored in the Nachos file "argv[0]", with* parameters stored in argv[1..argc-1] and return the* address space identifier*/SpaceId ExecV(int argc, char* argv[]);/* Only return once the user program "id" has finished.* Return the exit status.*/int Join(SpaceId id);/* File system operations: Create, Remove, Open, Read, Write, Close * These functions are patterned after UNIX -- files represent* both files *and* hardware I/O devices.** Note that the Nachos file system has a stub implementation, which * can be used to support these system calls if the regular Nachos* file system has not been implemented.*//* A unique identifier for an open Nachos file. */typedef int OpenFileId;/* when an address space starts up, it has two open files, representing* keyboard input and display output (in UNIX terms, stdin and stdout). * Read and Write can be used directly on these, without first opening * the console device.*/#define ConsoleInput 0#define ConsoleOutput 1/* Create a Nachos file, with name "name" *//* Note: Create does not open the file. *//* Return 1 on success, negative error code on failure */int Create(char *name);/* Remove a Nachos file, with name "name" */int Remove(char *name);/* Open the Nachos file "name", and return an "OpenFileId" that can* be used to read and write to the file. "mode" gives the requested* operation mode for this file.*/#define RO 1#define RW 2#define APPEND 3OpenFileId Open(char *name, int mode);/* Write "size" bytes from "buffer" to the open file.* Return the number of bytes actually read on success.* On failure, a negative error code is returned.*/int Write(char *buffer, int size, OpenFileId id);/* Read "size" bytes from the open file into "buffer".* Return the number of bytes actually read -- if the open file isn't* long enough, or if it is an I/O device, and there aren't enough* characters to read, return whatever is available (for I/O devices,* you should always wait until you can return at least one character).*/int Read(char *buffer, int size, OpenFileId id);/* Set the seek position of the open file "id"* to the byte "position".*/int Seek(int position, OpenFileId id);/* Deletes a file with the filename given by "name".* An error is returned if file does not exist or other wicked things happen. */int Delete(char* name);/* Close the file, we're done reading and writing to it.* Return 1 on success, negative error code on failure*/int Close(OpenFileId id);/* User-level thread operations: Fork and Yield. To allow multiple* threads to run within a user program.** Could define other operations, such as LockAcquire, LockRelease, etc. *//* Fork a thread to run a procedure ("func") in the *same* address space* as the current thread.* Return a positive ThreadId on success, negative error code on failure*/ThreadId ThreadFork(void (*func)());/* Yield the CPU to another runnable thread, whether in this address space * or not.*/void ThreadYield();/** Blocks current thread until lokal thread ThreadID exits with ThreadExit. * Function returns the ExitCode of ThreadExit() of the exiting thread.*/int ThreadJoin(ThreadId id);/** Deletes current thread and returns ExitCode to every waiting lokal thread. */void ThreadExit(int ExitCode);/** Returns SpaceId of current address space.*/SpaceId getSpaceID();/** Returns ThreadId of current thread.*/ThreadId getThreadID();/** IPC Inter Process Communication*/void Ipc(int sendDescriptor, SpaceId r_space, ThreadId r_thread, int s_msg0, int s_msg1,int receiveDescriptor, SpaceId * s_space, ThreadId * s_thread,int * r_msg0, int * r_msg1);/** returns the current cycle counter.*/unsigned int Clock();#endif /* IN_ASM */#endif /* SYSCALL_H */。

相关文档
最新文档