Compare commits

...

5 Commits

Author SHA1 Message Date
ginger88895 36a4dab13a Update 2019-05-02 22:52:00 +08:00
ginger88895 a114fc9a74 Finished all parts 2019-05-02 22:06:31 +08:00
ginger88895 b0db63c1d4 Finished all parts without bullet-proof 2019-05-02 21:51:04 +08:00
ginger88895 ae15de9334 Finished part 3 prototype 2019-05-02 18:21:43 +08:00
ginger88895 896a089252 Finished part 2 prototype 2019-05-01 17:12:12 +08:00
47 changed files with 631 additions and 91 deletions

13
proj2/dump Normal file
View File

@ -0,0 +1,13 @@
nachos 5.0j initializing... config interrupt timer processor console user-check grader
*** thread 0 looped 0 times
*** thread 0 looped 1 times
*** thread 1 looped 0 times
*** thread 0 looped 2 times
*** thread 1 looped 1 times
*** thread 0 looped 3 times
*** thread 1 looped 2 times
*** thread 0 looped 4 times
*** thread 1 looped 3 times
*** thread 1 looped 4 times
Testing the console device. Typed characters
will be echoed until q is typed.

View File

@ -8,7 +8,7 @@ Processor.usingTLB = false
Processor.numPhysPages = 64
ElevatorBank.allowElevatorGUI = false
NachosSecurityManager.fullySecure = false
ThreadedKernel.scheduler = nachos.threads.RoundRobinScheduler #nachos.threads.LotteryScheduler
ThreadedKernel.scheduler = nachos.threads.LotteryScheduler
Kernel.shellProgram = halt.coff #sh.coff
Kernel.processClassName = nachos.userprog.UserProcess
Kernel.kernel = nachos.userprog.UserKernel

View File

@ -9,6 +9,7 @@
# setenv ARCHDIR ../mips-x86.win32-xgcc
# you need to point to the right executables
ARCHDIR = ../../mips-x86.linux-xgcc
GCCDIR = $(ARCHDIR)/mips-
ASFLAGS = -mips1
@ -32,8 +33,7 @@ STDLIB_O = start.o stdio.o stdlib.o
LIB = assert atoi printf readline stdio strncmp strcat strcmp strcpy strlen memcpy memset
NLIB = libnachos.a
#TARGETS = halt sh matmult sort echo cat cp mv rm #chat chatserver
TARGETS = mytest1
TARGETS = halt sh matmult sort echo cat cp mv rm mytest1 mytest2a mytest2b mytest2c mytest2d mytest3 mytest4 #chat chatserver
.SECONDARY: $(patsubst %.c,%.o,$(wildcard *.c))

BIN
test/cp.coff Normal file

Binary file not shown.

BIN
test/cp.o Normal file

Binary file not shown.

BIN
test/echo.coff Normal file

Binary file not shown.

BIN
test/echo.o Normal file

Binary file not shown.

Binary file not shown.

BIN
test/matmult.coff Normal file

Binary file not shown.

BIN
test/matmult.o Normal file

Binary file not shown.

BIN
test/mv.coff Normal file

Binary file not shown.

BIN
test/mv.o Normal file

Binary file not shown.

View File

@ -2,14 +2,23 @@
#include "stdio.h"
char buf[100];
char* tt[]={"hello!","welcome!"};
int main()
{
printf("pid=%d\n",exec("mytest2a.coff",0,0));
printf("pid=%d\n",exec("mytest2b.coff",0,0));
printf("pid=%d\n",exec("mytest2d.coff",2,tt));
//exec("mytest2c.coff",0,0);
while(1);
return 0;
/*
int ff=creat("data");
close(ff);
write(1,"10 200\n",strlen("10 200\n"));
printf("%d\n",write(ff,"10 200\n",10));
halt();
return 0;
*/
/*
int a=0,b=0,i=0;
@ -33,7 +42,7 @@ int main()
}
printf("%d+%d=%d\n",a,b,a+b);
halt();
*/
return 0;
*/
}

Binary file not shown.

Binary file not shown.

11
test/mytest2a.c Normal file
View File

@ -0,0 +1,11 @@
#include "syscall.h"
#include "stdio.h"
int xid=5;
int main()
{
int id=5;
while(1);
return 0;
}

BIN
test/mytest2a.coff Normal file

Binary file not shown.

BIN
test/mytest2a.o Normal file

Binary file not shown.

11
test/mytest2b.c Normal file
View File

@ -0,0 +1,11 @@
#include "syscall.h"
#include "stdio.h"
int xid=7;
int main()
{
int id=7;
while(1);
return 0;
}

BIN
test/mytest2b.coff Normal file

Binary file not shown.

BIN
test/mytest2b.o Normal file

Binary file not shown.

16
test/mytest2c.c Normal file
View File

@ -0,0 +1,16 @@
#include "syscall.h"
#include "stdio.h"
char buf[100];
int main()
{
while(1)
{
int f=open("pool");
read(f,buf,100);
printf("%s\n",buf);
close(f);
}
return 0;
}

BIN
test/mytest2c.coff Normal file

Binary file not shown.

BIN
test/mytest2c.o Normal file

Binary file not shown.

14
test/mytest2d.c Normal file
View File

@ -0,0 +1,14 @@
#include "syscall.h"
#include "stdio.h"
char buf[100];
int main(int argc,char** argv)
{
while(1)
{
//printf("%s\n",argv[0]);
//printf("%s\n",argv[1]);
}
return 0;
}

BIN
test/mytest2d.coff Normal file

Binary file not shown.

BIN
test/mytest2d.o Normal file

Binary file not shown.

75
test/mytest3.c Normal file
View File

@ -0,0 +1,75 @@
#include "syscall.h"
#include "stdio.h"
char buf[100];
char* tt[]={"hello!","welcome!"};
int main()
{
int cid,tmp;
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
cid=exec("mytest4.coff",0,0);
printf("pid=%d\n",cid);
join(cid,&tmp);
halt();
return 0;
}

BIN
test/mytest3.coff Normal file

Binary file not shown.

BIN
test/mytest3.o Normal file

Binary file not shown.

14
test/mytest4.c Normal file
View File

@ -0,0 +1,14 @@
#include "syscall.h"
#include "stdio.h"
int main()
{
int i=0;
for(i=0;i<10000;i++)
{
if(i%10000==0)
printf("i=%d\n",i);
}
return 12;
}

BIN
test/mytest4.coff Normal file

Binary file not shown.

BIN
test/mytest4.o Normal file

Binary file not shown.

BIN
test/rm.coff Normal file

Binary file not shown.

BIN
test/rm.o Normal file

Binary file not shown.

BIN
test/sh.coff Normal file

Binary file not shown.

BIN
test/sh.o Normal file

Binary file not shown.

BIN
test/sort.coff Normal file

Binary file not shown.

BIN
test/sort.o Normal file

Binary file not shown.

View File

@ -4,7 +4,9 @@ import nachos.machine.*;
import java.util.TreeSet;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;
/**
* A scheduler that chooses threads using a lottery.
@ -30,8 +32,60 @@ public class LotteryScheduler extends PriorityScheduler {
/**
* Allocate a new lottery scheduler.
*/
public LotteryScheduler() {
public LotteryScheduler()
{
num_tickets=0;
rng=new Random();
thread_original_tickets=new HashMap<KThread,Integer>();
thread_effective_tickets=new HashMap<KThread,Integer>();
upstream=new HashMap<KThread,HashMap<KThread,Integer>>();
}
public int getPriority(KThread thread)
{
Lib.assertTrue(Machine.interrupt().disabled());
init_thread_tickets(thread);
return thread_original_tickets.get(thread);
}
public int getEffectivePriority(KThread thread)
{
Lib.assertTrue(Machine.interrupt().disabled());
init_thread_tickets(thread);
return thread_effective_tickets.get(thread);
}
public void setPriority(KThread thread,int priority)
{
Lib.assertTrue(Machine.interrupt().disabled());
Lib.assertTrue(priority>=min_tickets&&priority<=max_tickets);
init_thread_tickets(thread);
update(thread,priority-thread_original_tickets.get(thread));
}
public boolean increasePriority()
{
boolean intStatus = Machine.interrupt().disable();
KThread thread = KThread.currentThread();
int priority=getPriority(thread);
if(priority==priorityMaximum)
return false;
update(thread,1);
Machine.interrupt().restore(intStatus);
return true;
}
public boolean decreasePriority()
{
boolean intStatus = Machine.interrupt().disable();
KThread thread = KThread.currentThread();
int priority=getPriority(thread);
if(priority==priorityMinimum)
return false;
update(thread,-1);
Machine.interrupt().restore(intStatus);
return true;
}
/**
* Allocate a new lottery thread queue.
@ -41,8 +95,116 @@ public class LotteryScheduler extends PriorityScheduler {
* to the owning thread.
* @return a new lottery thread queue.
*/
public ThreadQueue newThreadQueue(boolean transferPriority) {
// implement me
return null;
public ThreadQueue newThreadQueue(boolean transferPriority)
{
return new lottery_queue(transferPriority);
}
protected void init_thread_tickets(KThread x)
{
if(!thread_original_tickets.containsKey(x))
{
num_tickets+=1;
thread_original_tickets.put(x,1);
thread_effective_tickets.put(x,1);
upstream.put(x,new HashMap<KThread,Integer>());
}
}
protected void update(KThread x,int amount)
{
//System.out.println("Update effective tickets by "+amount+": "+x);
num_tickets+=amount;
thread_effective_tickets.put(x,thread_effective_tickets.get(x)+amount);
HashMap<KThread,Integer> tmp=upstream.get(x);
for(KThread y:tmp.keySet())
if(tmp.get(y)!=0)
update(y,tmp.get(y)*amount);
}
protected void add_upstream(KThread x,KThread y)
{
update(y,thread_effective_tickets.get(x));
if(!upstream.get(x).containsKey(y))
upstream.get(x).put(y,1);
else
upstream.get(x).put(y,upstream.get(x).get(y)+1);
}
protected void remove_upstream(KThread x,KThread y)
{
update(y,-thread_effective_tickets.get(x));
upstream.get(x).put(y,upstream.get(x).get(y)-1);
}
protected class lottery_queue extends ThreadQueue
{
public lottery_queue(boolean transfer)
{
this.transfer=transfer;
acquiring_process=null;
waiting_queue=new HashSet<KThread>();
}
public void waitForAccess(KThread thread)
{
init_thread_tickets(thread);
waiting_queue.add(thread);
if(transfer&&acquiring_process!=null)
add_upstream(thread,acquiring_process);
}
public void acquire(KThread thread)
{
init_thread_tickets(thread);
acquiring_process=thread;
if(transfer)
for(KThread x:waiting_queue)
add_upstream(x,thread);
}
public KThread nextThread()
{
if(waiting_queue.isEmpty())
{
acquiring_process=null;
return null;
}
KThread result=null;
int waiting_sum=0;
for(KThread x:waiting_queue)
waiting_sum+=thread_effective_tickets.get(x);
int win=rng.nextInt(waiting_sum),acc=0;
for(KThread x:waiting_queue)
if(acc<=win&&win<acc+thread_effective_tickets.get(x))
{
result=x;
break;
}
else
acc+=thread_effective_tickets.get(x);
if(transfer&&acquiring_process!=null)
for(KThread x:waiting_queue)
remove_upstream(x,acquiring_process);
waiting_queue.remove(result);
acquiring_process=result;
if(transfer)
for(KThread x:waiting_queue)
add_upstream(x,acquiring_process);
return result;
}
public void print()
{
}
public boolean transfer;
private KThread acquiring_process;
private HashSet<KThread> waiting_queue;
}
protected int num_tickets=0;
protected static HashMap<KThread,Integer> thread_original_tickets;
protected static HashMap<KThread,Integer> thread_effective_tickets;
protected static HashMap<KThread,HashMap<KThread,Integer>> upstream;
public static final int min_tickets=1;
public static final int max_tickets=Integer.MAX_VALUE;
protected static Random rng;
}

View File

@ -4,6 +4,10 @@ import nachos.machine.*;
import nachos.threads.*;
import nachos.userprog.*;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.HashSet;
/**
* A kernel that can support multiple user processes.
*/
@ -19,14 +23,35 @@ public class UserKernel extends ThreadedKernel {
* Initialize this kernel. Creates a synchronized console and sets the
* processor's exception handler.
*/
public void initialize(String[] args) {
super.initialize(args);
public void initialize(String[] args)
{
super.initialize(args);
console = new SynchConsole(Machine.console());
Machine.processor().setExceptionHandler(new Runnable() {
public void run() { exceptionHandler(); }
});
console = new SynchConsole(Machine.console());
Machine.processor().setExceptionHandler(new Runnable() {
public void run() { exceptionHandler(); }
});
//Initialize free page list
fp_lock=new Semaphore(1);
fp_lock.P();
free_pages=new LinkedList<Integer>();
int num_phys_pages=Machine.processor().getNumPhysPages();
for(int i=0;i<num_phys_pages;i++)
free_pages.add(i);
fp_lock.V();
process_lock=new Semaphore(1);
process_lock.P();
process_table=new HashMap<Integer,UserProcess>();
process_return=new HashMap<Integer,Integer>();
process_tree=new HashMap<Integer,HashSet<Integer>>();
process_fin=new HashMap<Integer,Integer>();
process_free_pid=new LinkedList<Integer>();
process_pool_size=0;
process_lock.V();
}
/**
@ -89,15 +114,15 @@ public class UserKernel extends ThreadedKernel {
*
* @see nachos.machine.Machine#getShellProgramName
*/
public void run() {
super.run();
public void run()
{
super.run();
UserProcess process = UserProcess.newUserProcess();
String shellProgram = Machine.getShellProgramName();
Lib.assertTrue(process.execute(shellProgram, new String[] { }));
UserProcess process = UserProcess.newUserProcess();
String shellProgram = Machine.getShellProgramName();
Lib.assertTrue(process.execute(shellProgram, new String[] { }));
KThread.currentThread().finish();
KThread.currentThread().finish();
}
/**
@ -109,6 +134,16 @@ public class UserKernel extends ThreadedKernel {
/** Globally accessible reference to the synchronized console. */
public static SynchConsole console;
public static LinkedList<Integer> free_pages;
public static Semaphore fp_lock;
public static HashMap<Integer,UserProcess> process_table;
public static HashMap<Integer,HashSet<Integer>> process_tree;
public static HashMap<Integer,Integer> process_return;
public static HashMap<Integer,Integer> process_fin;
public static LinkedList<Integer> process_free_pid;
public static Semaphore process_lock;
public static int process_pool_size;
// dummy variables to make javac smarter
private static Coff dummy1 = null;

View File

@ -5,6 +5,7 @@ import nachos.threads.*;
import nachos.userprog.*;
import java.io.EOFException;
import java.util.HashSet;
/**
* Encapsulates the state of a user process that is not contained in its
@ -25,8 +26,12 @@ public class UserProcess {
public UserProcess() {
int numPhysPages = Machine.processor().getNumPhysPages();
pageTable = new TranslationEntry[numPhysPages];
cond_lock=new Lock();
cond=new Condition(cond_lock);
/*
for (int i=0; i<numPhysPages; i++)
pageTable[i] = new TranslationEntry(i,i, true,false,false,false);
*/
}
/**
@ -37,7 +42,9 @@ public class UserProcess {
* @return a new process of the correct class.
*/
public static UserProcess newUserProcess() {
return (UserProcess)Lib.constructObject(Machine.getProcessClassName());
//TODO: Remove this line!!!
return new UserProcess();
//return (UserProcess)Lib.constructObject(Machine.getProcessClassName());
}
/**
@ -51,14 +58,25 @@ public class UserProcess {
public boolean execute(String name, String[] args) {
if (!load(name, args))
return false;
new UThread(this).setName(name).fork();
descs=new OpenFile[16];
descs[0]=UserKernel.console.openForReading();
descs[1]=UserKernel.console.openForWriting();
for(int i=2;i<16;i++)
descs[i]=null;
UserKernel.process_lock.P();
//Simply increment the counter for now
UserKernel.process_pool_size+=1;
pid=UserKernel.process_pool_size;
UserKernel.process_table.put(pid,this);
UserKernel.process_tree.put(pid,new HashSet<Integer>());
UserKernel.process_fin.put(pid,0);
UserKernel.process_lock.V();
thread=new UThread(this);
thread.setName(name).fork();
return true;
}
@ -98,6 +116,12 @@ public class UserProcess {
int bytesRead = readVirtualMemory(vaddr, bytes);
/*
System.out.println("Read:");
for(int i=0;i<bytesRead;i++)
System.out.println(bytes[i]);
*/
for (int length=0; length<bytesRead; length++) {
if (bytes[length] == 0)
return new String(bytes, 0, length);
@ -132,20 +156,28 @@ public class UserProcess {
* the array.
* @return the number of bytes successfully transferred.
*/
public int readVirtualMemory(int vaddr, byte[] data, int offset,
int length) {
Lib.assertTrue(offset >= 0 && length >= 0 && offset+length <= data.length);
public int readVirtualMemory(int vaddr, byte[] data, int offset, int length)
{
byte[] memory = Machine.processor().getMemory();
byte[] memory = Machine.processor().getMemory();
// for now, just assume that virtual addresses equal physical addresses
if (vaddr < 0 || vaddr >= memory.length)
return 0;
int vpn=vaddr/pageSize;
if(vaddr<0||vpn>=numPages)
return 0;
int amount = Math.min(length, memory.length-vaddr);
System.arraycopy(memory, vaddr, data, offset, amount);
return amount;
int total=0;
for(int i=vpn;i<numPages;i++)
{
int amount=Math.min(length,(i+1)*pageSize-vaddr);
int ppn_offs=vaddr-i*pageSize;
if(amount<=0)
break;
System.arraycopy(memory,pageTable[i].ppn*pageSize+ppn_offs,data,offset,amount);
offset+=amount;
vaddr+=amount;
length-=amount;
total+=amount;
}
return total;
}
/**
@ -175,20 +207,28 @@ public class UserProcess {
* virtual memory.
* @return the number of bytes successfully transferred.
*/
public int writeVirtualMemory(int vaddr, byte[] data, int offset,
int length) {
Lib.assertTrue(offset >= 0 && length >= 0 && offset+length <= data.length);
public int writeVirtualMemory(int vaddr, byte[] data, int offset, int length)
{
byte[] memory = Machine.processor().getMemory();
int vpn=vaddr/pageSize;
if(vaddr<0||vpn>=numPages)
return 0;
byte[] memory = Machine.processor().getMemory();
// for now, just assume that virtual addresses equal physical addresses
if (vaddr < 0 || vaddr >= memory.length)
return 0;
int amount = Math.min(length, memory.length-vaddr);
System.arraycopy(data, offset, memory, vaddr, amount);
return amount;
int total=0;
for(int i=vpn;i<numPages;i++)
{
int amount=Math.min(length,(i+1)*pageSize-vaddr);
int ppn_offs=vaddr-i*pageSize;
if(amount<=0)
break;
System.arraycopy(data,offset,memory,pageTable[i].ppn*pageSize+ppn_offs,amount);
offset+=amount;
vaddr+=amount;
length-=amount;
total+=amount;
}
return total;
}
/**
@ -286,36 +326,56 @@ public class UserProcess {
*
* @return <tt>true</tt> if the sections were successfully loaded.
*/
protected boolean loadSections() {
if (numPages > Machine.processor().getNumPhysPages()) {
coff.close();
Lib.debug(dbgProcess, "\tinsufficient physical memory");
return false;
}
protected boolean loadSections()
{
UserKernel.fp_lock.P();
int num_free_pages=UserKernel.free_pages.size();
if(numPages>num_free_pages)
{
coff.close();
Lib.debug(dbgProcess,"\tinsufficient physical memory");
UserKernel.fp_lock.V();
return false;
}
// load sections
for (int s=0; s<coff.getNumSections(); s++) {
CoffSection section = coff.getSection(s);
Lib.debug(dbgProcess, "\tinitializing " + section.getName()
+ " section (" + section.getLength() + " pages)");
//allocate
for(int i=0;i<numPages;i++)
{
Integer x=UserKernel.free_pages.getFirst();
pageTable[i]=new TranslationEntry(i,x,true,false,false,false);
Lib.debug(dbgProcess,"\tassigning physical page "+x);
UserKernel.free_pages.remove(x);
}
for (int i=0; i<section.getLength(); i++) {
int vpn = section.getFirstVPN()+i;
// for now, just assume virtual addresses=physical addresses
section.loadPage(i, vpn);
}
}
return true;
// load sections
for (int s=0; s<coff.getNumSections(); s++)
{
CoffSection section = coff.getSection(s);
Lib.debug(dbgProcess, "\tinitializing " + section.getName() + " section (" + section.getLength() + " pages)");
for (int i=0; i<section.getLength(); i++)
{
int vpn = section.getFirstVPN()+i;
section.loadPage(i, pageTable[vpn].ppn);
}
}
UserKernel.fp_lock.V();
return true;
}
/**
* Release any resources allocated by <tt>loadSections()</tt>.
*/
protected void unloadSections() {
}
protected void unloadSections()
{
UserKernel.fp_lock.P();
for(int i=0;i<numPages;i++)
{
UserKernel.free_pages.add(pageTable[i].ppn);
pageTable[i]=null;
}
UserKernel.fp_lock.V();
}
/**
* Initialize the processor's registers in preparation for running the
@ -343,12 +403,11 @@ public class UserProcess {
/**
* Handle the halt() system call.
*/
private int handleHalt() {
Machine.halt();
Lib.assertNotReached("Machine.halt() did not halt machine!");
return 0;
private int handleHalt()
{
if(pid==1)
Machine.halt();
return 0;
}
@ -364,6 +423,40 @@ public class UserProcess {
syscallClose = 8,
syscallUnlink = 9;
public int handleExit(int status)
{
UserKernel.process_lock.P();
UserKernel.process_fin.put(pid,1);
UserKernel.process_return.put(pid,status);
UserKernel.process_lock.V();
cond_lock.acquire();
cond.wakeAll();
cond_lock.release();
//Do some extra cleanup
unloadSections();
coff.close();
for(int i=0;i<16;i++)
if(descs[i]!=null)
descs[i].close();
if(pid==1)
Machine.halt();
thread.finish();
return 0;
}
private byte[] bytearray_create_safe(int size)
{
if(size<0||size>numPages*pageSize)
return null;
return new byte[size];
}
/**
* Handle a syscall exception. Called by <tt>handleException()</tt>. The
* <i>syscall</i> argument identifies which syscall the user executed:
@ -394,24 +487,97 @@ public class UserProcess {
*/
public int handleSyscall(int syscall, int a0, int a1, int a2, int a3)
{
System.out.println("System Call: "+syscall);
String fn;
String[] argz;
byte[] buf;
int len;
int len,val,tmp;
UserProcess child;
boolean status;
switch (syscall)
{
case syscallHalt:
return handleHalt();
case syscallExit:
return handleExit(a0);
case syscallExec:
fn=readVirtualMemoryString(a0,256);
if(fn!=null&&fn.lastIndexOf('.')!=-1&&fn.substring(fn.lastIndexOf('.')).equals(".coff"))
{
buf=bytearray_create_safe(4*a1);
if(buf==null)
return -1;
argz=new String[a1];
readVirtualMemory(a2,buf,0,4*a1);
tmp=0;
for(int i=0;i<4*a1;i++)
{
tmp+=((((int)(buf[i]))&0xFF)<<(8*(i%4)));
if(i%4==3)
{
argz[i/4]=readVirtualMemoryString(tmp,256);
if(argz[i/4]==null)
argz[i/4]=new String();
tmp=0;
}
}
child=UserProcess.newUserProcess();
status=child.execute(fn,argz);
if(status)
{
UserKernel.process_lock.P();
UserKernel.process_tree.get(pid).add(child.pid);
UserKernel.process_lock.V();
return child.pid;
}
return -1;
}
return -1;
case syscallJoin:
UserKernel.process_lock.P();
if(!UserKernel.process_tree.get(pid).contains(a0))
{
UserKernel.process_lock.V();
return -1;
}
tmp=UserKernel.process_fin.get(a0);
if(tmp==1)
{
val=UserKernel.process_return.get(a0);
UserKernel.process_lock.V();
}
else
{
child=UserKernel.process_table.get(a0);
UserKernel.process_lock.V();
child.cond_lock.acquire();
child.cond.sleep();
child.cond_lock.release();
UserKernel.process_lock.P();
val=UserKernel.process_return.get(a0);
UserKernel.process_lock.V();
}
buf=new byte[4];
for(int i=0;i<4;i++)
buf[i]=(byte)(((val>>(8*i))%(1<<8))&0xFF);
writeVirtualMemory(a1,buf,0,4);
if(val==-1)
return 0;
else
return 1;
case syscallCreate:
fn=readVirtualMemoryString(a0,256);
if(fn!=null)
{
//System.out.println("I am going to create a file name "+fn);
OpenFile tf=ThreadedKernel.fileSystem.open(fn,true);
if(tf==null)
return -1;
for(int i=2;i<16;i++)
for(int i=0;i<16;i++)
if(descs[i]==null)
{
descs[i]=tf;
@ -419,14 +585,12 @@ public class UserProcess {
}
return -1;
}
System.out.println("Bloody hell");
return -1;
case syscallOpen:
fn=readVirtualMemoryString(a0,256);
if(fn!=null)
{
//System.out.println("I am going to open a file name "+fn);
OpenFile tf=ThreadedKernel.fileSystem.open(fn,false);
if(tf==null)
return -1;
@ -438,26 +602,35 @@ public class UserProcess {
}
return -1;
}
System.out.println("Bloody hell");
return -1;
case syscallRead:
if(a0<0||a0>=16)
return -1;
if(descs[a0]==null)
return -1;
buf=new byte[a2];
buf=bytearray_create_safe(a2);
if(buf==null)
return -1;
len=descs[a0].read(buf,0,a2);
if(len<0)
return -1;
return writeVirtualMemory(a1,buf,0,len);
case syscallWrite:
if(a0<0||a0>=16)
return -1;
if(descs[a0]==null)
return -1;
buf=new byte[a2];
buf=bytearray_create_safe(a2);
if(buf==null)
return -1;
len=readVirtualMemory(a1,buf,0,a2);
return descs[a0].write(buf,0,len);
case syscallClose:
if(a0<0||a0>=16)
return -1;
if(descs[a0]!=null)
descs[a0].close();
descs[a0]=null;
@ -503,9 +676,10 @@ public class UserProcess {
break;
default:
Lib.debug(dbgProcess, "Unexpected exception: " +
Processor.exceptionNames[cause]);
Lib.assertNotReached("Unexpected exception");
Lib.debug(dbgProcess, "Unexpected exception: " + Processor.exceptionNames[cause]);
handleExit(-1);
//Lib.assertNotReached("Unexpected exception");
}
}
@ -526,4 +700,10 @@ public class UserProcess {
private static final int pageSize = Processor.pageSize;
private static final char dbgProcess = 'a';
private OpenFile descs[];
public int pid;
public Lock cond_lock;
public Condition cond;
private UThread thread;
}