当前位置:文档之家› 操作系统课程设计实验报告proj2

操作系统课程设计实验报告proj2

操作系统课程设计报告班级:团队成员:目录 ................................................................................................................... 错误!未定义书签。

一、实验要求:建立线程系统...................................................................... 错误!未定义书签。

1.1Task 2.1实现文件系统调用 (3)1.1.1题目要求 (3)1.1.2题目分析与实现方案 (3)1.1.3关键点与难点 (4)1.1.4实现代码 (4)1.2 Task 2.2 完成对多道程序的支持 (5)1.2.1题目要求 (5)1.2.2题目分析与实现方案 (5)1.2.3关键点与难点 (6)1.2.4实现代码 (7)1.3 Task 2.3 实现系统调用 (7)1.3.1题目要求 (7)1.3.2题目分析与实现方案 (8)1.3.3关键点与难点 (9)1.3.4实现代码 (9)1.4 Task 2.4 实现彩票调度 (10)1.4.1题目要求 (10)1.4.2题目分析与实现方案 (10)1.4.3关键点与难点 (11)1.4.4实现代码 (11)二、测试结果............................................................................................... 2错误!未定义书签。

一、实验要求:多道程序设计1.1 Task2.1 实现文件系统调用1.1.1题目要求实现文件系统调用(创建,打开,读,写,关闭,unlink),在syscall.h中有详细的记录,可以看一下UserProcess.java中的代码,最好把你自己写的系统调用的代码也放在这里。

记住你不是在实现一个文件系统,而是在给用户进程获取我们给你定义好的文件系统的能力。

我们在start.s里为你提供了用户进程进行系统调用所必需的汇编代码。

(SYSCALL会为每个系统调用产生汇编代码)。

其中Unlink为删除目录相并减少一个连接数,如果链接数为0并且没有任何进程打开该文件,该文件内容才能被真正删除,但是若又进程打开了该文件,则文件暂时不删除直到所有打开该文件的进程都结束时文件才能被删除。

1.1.2题目分析与实现方案系统共提供了七个系统调用:halt (停机, 已经提供),creat (创建并打开磁盘文件),open (打开磁盘文件),read (读IO, 可以是磁盘或屏幕),write (写IO),close (关闭IO),unlink (删除磁盘文件)。

要确保如下几点:1)稳定性, 不能因为一个进程的非法系统调用就使操作系统崩溃, 而应该返回错误代码。

2)halt()调用只能由第一个进程(root process) 执行。

3)系统调用需要读写内存时, 通过readVirtualMemory和writeVirtualMemory进行。

4)文件名以null结尾, 不超过256字符。

5)如果系统调用出错, 应返回-1。

6)为每个打开的IO文件分配一个“文件描述符”, 用整数表示. 每个进程最多可以拥有16个。

其中0和1应分配给标准输入和标准输出(即屏幕),这由SynchConsole类管理。

不同进程可以用相同的文件描述符处理不同的文件。

7)Nachos已经提供了一个简单的文件系统FileSystem(Machine包中), 通过ThreadedKernel.fileSystem访问。

8)系统不需要考虑文件访问的互斥等问题。

方案:1)create系统调用:1.根据传入的fileAddress,从虚拟内存中读出文件名2.判断文件名是否存在,即fileAddress处是否有文件名3.如果不存在,直接创建。

先去找合适的位置,如果已经有大于16个,退出,否则创建,创建只需调用filesystem的open即可(传入的布尔值create为true)2)open系统调用:1.根据传入的fileAddress,从虚拟内存中读出文件名2.判断文件名是否存在,即fileAddress处是否有文件名3.先去找合适的位置,如果已经有大于16个,退出,否则创建只需调用filesystem的open即可(传入的布尔值create为false)4.维护本地描述符表3)read系统调用Read系统调用的三个参数依次为: 文件描述符, 写入的内存地址, 读取的字节数。

在Read系统调用中进行如下操作:1.如果打开文件大于16个或者小于0个,或者打开文件列表为空,直接返回。

2.创建数组temp,把文件内容读入temp,求出读出数据长度3.若读出数据小于0即为出错,返回。

4.把该数据写入虚拟内存。

5.返回写入内存的字节数4)write系统调用Write系统调用的三个参数依次为: 文件描述符, 读内存的地址, 写入文件的字节数。

在Write系统调用中进行如下操作:1.如果打开文件大于16个或者小于0个,或者打开文件列表为空,直接返回。

2.创建数组temp,把虚拟内存中的内容读入temp,得到读出数据长度3.若读出数据小于0即为出错,返回。

4.把该数据写入磁盘。

5.若写的数据长度小于读出的数据长度,则错误,返回错误代码5)close系统调用Close系统调用的唯一一个参数为文件描述符。

在Close系统调用中进行如下操作:1.如果打开文件大于16个或者小于0个,或者打开文件列表为空,直接返回。

2.如果不存在,关闭出错3.否则关闭,把openfile数组中fileDescriptor中的位置置为06)unlink系统调用:1.根据传入的fileAddress,从虚拟内存中读出文件名。

2.如果不存在,不必删除3.如果存在,就删除,出错返回错误代码一般地,在Unlink调用中只需读取文件名并执行fileSystem.remove 方法删除文件即可。

但是,一个文件可能被多个进程打开而不能立即删除,必须等所有打开这个文件的进程都关闭该文件后才能删除。

因此,在Close系统调用中还要增加如下内容:若文件关闭后它在全局文件表中已经不存在且文件名在删除队列中,则此时执行删除文件操作,并将文件从删除队列中移出。

1.1.3关键点与难点注意:以上系统调用只是在一般情况下函数的执行流程。

为了提高系统的健壮性, 在系统调用中还要进行下列错误检查:a)文件名长度不得超过256字符, 不得含有非法字符或空。

b)打开, 创建文件时, 局部描述符表不能满。

c)fileSystem的操作返回值必须正确。

d)readVirtualMemory和writeVirtualMemory的返回值必须正确。

1.1.4实现代码private int handleCreate(int fileAddress){// 限定文件名长度,readVirtualMemoryString 读取文件名String filename =readVirtualMemoryString(fileAddress,256);if(filename ==null)return-1;int fileDescriptor =findEmpty();if(fileDescriptor ==-1)return-1;else{// ThreadedKernel.fileSystem.open()打开文件(第二个参数为true表示创建新文件)openfile[fileDescriptor]=ThreadedKernel.fileSystem.open(filename,true);return fileDescriptor;}}private int handleOpen(int fileAddress){// 限定文件名长度String filename =readVirtualMemoryString(fileAddress,256);if(filename ==null)return-1;int fileDescriptor =findEmpty();// 为空,报错。

if(fileDescriptor ==-1)return-1;else{openfile[fileDescriptor]=ThreadedKernel.fileSystem.open(filename,false);return fileDescriptor;}}private int handleRead(int fileDescriptor,int bufferAddress,int length){// 如果打开文件大于16个或者小于0个,或者打开文件列表为空,直接返回。

if(fileDescriptor >15|| fileDescriptor <0||openfile[fileDescriptor]==null)return-1;byte temp[]=new byte[length];// 通过OpenFile.read读取文件内容int readNumber =openfile[fileDescriptor].read(temp,0, length);if(readNumber <=0)return0;// 把该数据写入虚拟内存。

int writeNumber =writeVirtualMemory(bufferAddress, temp);return writeNumber;}private int handleWrite(int fileDescriptor,int bufferAddress,int length){ // 如果打开文件大于16个或者小于0个,或者打开文件列表为空,直接返回。

if(fileDescriptor >15|| fileDescriptor <0||openfile[fileDescriptor]==null)return-1;// 文件未打开,出错// 创建数组temp,把虚拟内存中的内容读入temp,得到读出数据长度byte temp[]=new byte[length];int readNumber =readVirtualMemory(bufferAddress, temp);// 若读出数据小于0即为出错,返回。

if(readNumber <=0)return0;// 把该数据写入磁盘。

int writeNumber =openfile[fileDescriptor].write(temp,0, length);// 若写的数据长度小于读出的数据长度,则错误,返回错误代码if(writeNumber < length)return-1;// 返回写入文件的字节数return writeNumber;}private int handleClose(int fileDescriptor){// 如果打开文件大于16个或者小于0个,或者打开文件列表为空,直接返回。

相关主题