diff --git a/code/machine/machine.h b/code/machine/machine.h index 5422e22..f58b667 100644 --- a/code/machine/machine.h +++ b/code/machine/machine.h @@ -36,7 +36,7 @@ // the disk sector size, for // simplicity -#define NumPhysPages 64 // Increase this as necessary! +#define NumPhysPages 128 // Increase this as necessary! #define MemorySize (NumPhysPages * PageSize) #define TLBSize 4 // if there is a TLB, make it small diff --git a/code/test/start.S b/code/test/start.S index d79b2f4..353097d 100644 --- a/code/test/start.S +++ b/code/test/start.S @@ -213,7 +213,15 @@ ThreadExit: syscall j $31 .end ThreadExit - + + + .globl ForkExec + .ent ForkExec +ForkExec: + addiu $2,$0,SC_ForkExec + syscall + j $31 + .end ForkExec #endif /* dummy function to keep gcc happy */ diff --git a/code/test/userpages0 b/code/test/userpages0 index b624377..ce0fec1 100644 Binary files a/code/test/userpages0 and b/code/test/userpages0 differ diff --git a/code/threads/system.h b/code/threads/system.h index 2461e18..c0d2dda 100644 --- a/code/threads/system.h +++ b/code/threads/system.h @@ -34,7 +34,7 @@ extern Timer *timer; // the hardware alarm clock extern Machine *machine; // user program memory and registers #ifdef CHANGED -#define MAX_STRING_SIZE 8 +#define MAX_STRING_SIZE 64 #include "consoledriver.h" extern ConsoleDriver *consoledriver; // add console driver #include "pageprovider.h" diff --git a/code/userprog/exception.cc b/code/userprog/exception.cc index c8c0a83..88d244a 100644 --- a/code/userprog/exception.cc +++ b/code/userprog/exception.cc @@ -226,6 +226,14 @@ ExceptionHandler (ExceptionType which) do_ThreadExit(); break; } + case SC_ForkExec: + { + int s = machine->ReadRegister(4); + char * command = new char[MAX_STRING_SIZE]; + int size = copyStringFromMachine(s, command, MAX_STRING_SIZE); + do_ForkExec(command); + break; + } #endif default: { diff --git a/code/userprog/syscall.h b/code/userprog/syscall.h index 94c598a..3b930b3 100644 --- a/code/userprog/syscall.h +++ b/code/userprog/syscall.h @@ -40,6 +40,7 @@ #define SC_GetInt 16 #define SC_ThreadCreate 17 #define SC_ThreadExit 18 +#define SC_ForkExec 19 #endif #ifdef IN_USER_MODE @@ -148,6 +149,7 @@ void PutInt(int n); void GetInt( int * n); int ThreadCreate(void f(void * args), void * args); void ThreadExit(void); +int ForkExec ( const char * s); #endif // CHANGED diff --git a/code/userprog/userthread.cc b/code/userprog/userthread.cc index 9267df8..f93039e 100644 --- a/code/userprog/userthread.cc +++ b/code/userprog/userthread.cc @@ -88,8 +88,46 @@ void do_ThreadExit(){ if ( currentThread->space->threads == 0 ){ // No threads remains, desallocate addrspace delete currentThread->space; - Exit(0); + currentThread->space = NULL; } currentThread->Finish(); } + +void StartUserProc( void * args ){ + currentThread->space->InitRegisters(); + currentThread->space->RestoreState(); + machine->DumpMem("memory.svg"); + machine->Run(); +} + +int do_ForkExec( const char * c){ + DEBUG('x', "Enter ForkExec\n"); + AddrSpace * space; + Thread * fork; + OpenFile * file; + + file = fileSystem->Open(c); + + if (file == NULL) { + printf("Unable to open file %s\n", file); + return -1; + } + + try { + space = new AddrSpace(file); + }catch(const std::bad_alloc& e) { + printf("==> BAD ALLOC ERROR: no empty space\n"); + delete space; + ASSERT(false); + } + + fork = new Thread("forkThread"); + fork->space = space; + fork->Start(StartUserProc, NULL); + + delete file; + + return 0; +} + #endif diff --git a/code/userprog/userthread.h b/code/userprog/userthread.h index e49b51b..42028f8 100644 --- a/code/userprog/userthread.h +++ b/code/userprog/userthread.h @@ -11,4 +11,5 @@ typedef struct { extern int do_ThreadCreate(int f, int arg); extern void do_ThreadExit(); +extern int do_ForkExec( const char * s); #endif