adult_number_Molokai = 0; lock = new Lock();
children_condition_Oahu = new Condition(lock); children_condition_Molokai = new Condition(lock); adult_condition_Oahu = new Condition(lock); is_pilot = true;
is_adult_go = false; is_end = false;
boat_in_Oahu = true; }
static void AdultItinerary() { bg.initializeAdult(); lock.acquire();
if (!(is_adult_go && boat_in_Oahu)) { adult_condition_Oahu.sleep(); }
bg.AdultRowToMolokai(); adult_number_Oahu--; adult_number_Molokai++; is_adult_go = false; boat_in_Oahu = false;
children_condition_Molokai.wake(); lock.release(); }
static void ChildItinerary() { bg.initializeChild();
boolean is_on_Oahu = true; boolean is_first_go=true; lock.acquire(); while (!is_end) { if (is_on_Oahu) {
if (!boat_in_Oahu || is_adult_go) {
children_condition_Oahu.sleep(); }
if(is_pilot)
{bg.ChildRowToMolokai(); is_on_Oahu=false;
children_number_Oahu--; children_number_Molokai++; is_pilot = false;
children_condition_Oahu.wake();
children_condition_Molokai.sleep(); } else {
if (adult_number_Oahu == 0 && children_number_Oahu == 1) is_end = true;
if(adult_number_Oahu != 0) is_adult_go=true; bg.ChildRideToMolokai(); is_on_Oahu=false;
boat_in_Oahu = false; children_number_Oahu--; children_number_Molokai++; is_pilot = true; if(!is_end) {
children_condition_Molokai.wake(); }
children_condition_Molokai.sleep(); } }
else {
bg.ChildRowToOahu(); is_on_Oahu=true;
boat_in_Oahu = true;
children_number_Molokai--; children_number_Oahu++;
if (adult_number_Oahu == 0) { is_adult_go = false;
children_condition_Oahu.wake(); } else {
if(is_adult_go)
adult_condition_Oahu.wake(); else
children_condition_Oahu.wake(); }
children_condition_Oahu.sleep(); } } }
(c) 程序截图
这是三个孩子和三个大人的情况,图中显示程序正确。
Project2:
1 creat open read write close unlink文件系统调用
必须保证操作系统的内核不受到用户的错误影响,换句话说,用户进程产生的错误参数不能传入内核。修改halt()方法只能根进程可以调用;必须使用UserProcess.readVirtualMemory和UserProcess.writeVirtualMemory来把地址和参数传入。作为参数传递的字符串最长为256.文件描述符0和1是标准的输入输出流,不用open方法就能打开不用实现任何形式的锁,需要的只是提供的文件系统完成系统调用 (a) 设计思想
halt():设置一个进程号,只有进程号为0的进程(也就是第一个进程)才能
调用
creat():先从内存中将文件名读出,然后利用文件系统的打开文件。利用不
存在就创建的方法,在物理磁盘中创建文件。
open():先从内存中将文件名读出,然后利用文件系统的打开文件。利用不
存在直接返回null,仅打开
read():使用打开文件描述符,利用文件系统的读方法将数据从文件中读到
数组中,然后使用内存写操作,写入内存。返回写入的数量
write():使用打开文件描述符,利用内存读操作将数据从内存中读到数组中,
然后使用文件写操作,写入文件。返回写入的数量
close():使用打开文件描述符,将文件描述符指向的文件利用文件系统的关
闭方法关闭
unlink():先从内存中将文件名读出,利用文件系统的删除操作将文件从物
理磁盘中删除
(b) 源代码
private int handleHalt() { if(pid==0)
Machine.halt();
Lib.assertNotReached(\); return 0; }
private int handleCreate(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, 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) {
if(fileDescriptor>15||fileDescriptor<0||openfile[fileDescriptor]==null)
return -1;
byte temp[]=new byte[length];
int readNumber=openfile[fileDescriptor].read(temp, 0, length); if(readNumber<=0) return 0;
int writeNumber=writeVirtualMemory(bufferAddress,temp); return writeNumber; }
private int handleWrite(int fileDescriptor,int bufferAddress,int length){
if(fileDescriptor>15||fileDescriptor<0||openfile[fileDescriptor]==null)
return -1//文件未打开,出错 byte temp[]=new byte[length];
int readNumber=readVirtualMemory(bufferAddress, temp); if(readNumber<=0)
return 0;//没读出数据
int writeNumber=openfile[fileDescriptor].write(temp, 0, length); if(writeNumber return -1;//未完全写入,出错 return writeNumber; } private int handleClose(int fileDescriptor) { if(fileDescriptor>15||fileDescriptor<0||openfile[fileDescriptor]==null) return -1;//文件不存在,关闭出错 openfile[fileDescriptor].close(); openfile[fileDescriptor]=null; return 0; } private int handleUnlink(int fileAddress) { String filename=readVirtualMemoryString(fileAddress,256); if(filename==null) return 0; if(ThreadedKernel.fileSystem.remove(filename)) return 0; else