From 6bd3e1338fad01be426b01c2e3312496a3832144 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Mon, 15 Nov 2021 00:42:30 +0100 Subject: [PATCH] TD2 I.5 first working version of Thread Add semaphore to PutChar and GetChar --- .gitignore | 1 + code/Makefile.dep | 4 +-- code/test/threadcreate.c | 13 ++++++++++ code/userprog/addrspace.cc | 9 +++++++ code/userprog/addrspace.h | 4 ++- code/userprog/consoledriver.cc | 15 ++++++++++- code/userprog/userthread.cc | 47 ++++++++++++++++++++++++++++++++++ code/userprog/userthread.h | 6 +++++ 8 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 code/test/threadcreate.c diff --git a/.gitignore b/.gitignore index 2c13b49..d30b159 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,6 @@ code/test/putint code/test/putstring code/test/shell code/test/sort +code/test/threadcreate code/threads/nachos code/userprog/nachos diff --git a/code/Makefile.dep b/code/Makefile.dep index 1678db3..e42a43b 100644 --- a/code/Makefile.dep +++ b/code/Makefile.dep @@ -41,8 +41,8 @@ CFLAGS += -fsanitize=undefined LDFLAGS += -fsanitize=undefined # décommenté TD1 - partie V -CFLAGS += -fsanitize=address -LDFLAGS += -fsanitize=address -lpthread +#CFLAGS += -fsanitize=address +#LDFLAGS += -fsanitize=address -lpthread endif ifeq ($(NACHOS_SYS),MAC_OS_SYS) diff --git a/code/test/threadcreate.c b/code/test/threadcreate.c new file mode 100644 index 0000000..bae750f --- /dev/null +++ b/code/test/threadcreate.c @@ -0,0 +1,13 @@ +#ifdef CHANGED +#include "syscall.h" + +void f(int c) { + PutString("Thead!"); +} + +int main(){ + //int i; + ThreadCreate(f, 66); + PutString("end of main()\n"); +} +#endif diff --git a/code/userprog/addrspace.cc b/code/userprog/addrspace.cc index 4b96a5c..9543006 100644 --- a/code/userprog/addrspace.cc +++ b/code/userprog/addrspace.cc @@ -292,3 +292,12 @@ AddrSpace::RestoreState () machine->currentPageTable = pageTable; machine->currentPageTableSize = numPages; } + +#ifdef CHANGED +int +AddrSpace::AllocateUserStack() +{ + int memory = numPages * PageSize; + return memory - 256; +} +#endif diff --git a/code/userprog/addrspace.h b/code/userprog/addrspace.h index 2c319f6..a5169a9 100644 --- a/code/userprog/addrspace.h +++ b/code/userprog/addrspace.h @@ -40,7 +40,9 @@ class AddrSpace:public dontcopythis unsigned blocksize); // Dump program layout as SVG unsigned NumPages() { return numPages; } - + #ifdef CHANGED + int AllocateUserStack(); + #endif private: NoffHeader noffH; // Program layout diff --git a/code/userprog/consoledriver.cc b/code/userprog/consoledriver.cc index e409caa..f0552c4 100644 --- a/code/userprog/consoledriver.cc +++ b/code/userprog/consoledriver.cc @@ -6,6 +6,8 @@ static Semaphore *readAvail; static Semaphore *writeDone; +static Semaphore *m_PutChar; +static Semaphore *m_GetChar; static void ReadAvailHandler(void *arg) { (void) arg; readAvail->V(); } static void WriteDoneHandler(void *arg) { (void) arg; writeDone->V(); } @@ -15,6 +17,11 @@ ConsoleDriver::ConsoleDriver(const char *in, const char *out) readAvail = new Semaphore("read avail", 0); writeDone = new Semaphore("write done", 0); console = new Console (in, out, ReadAvailHandler, WriteDoneHandler, NULL); + + // Add these semaphores because we had problems with threads + // Assert error on putBusy + m_PutChar = new Semaphore("PutChar", 1); + m_GetChar = new Semaphore("GetChar", 1); } ConsoleDriver::~ConsoleDriver() @@ -22,18 +29,24 @@ ConsoleDriver::~ConsoleDriver() delete console; delete writeDone; delete readAvail; + delete m_PutChar; + delete m_GetChar; } void ConsoleDriver::PutChar( int ch) { + m_PutChar->P(); console->TX(ch); - writeDone->P(); + writeDone->P(); + m_PutChar->V(); } int ConsoleDriver::GetChar() { + m_GetChar->P(); readAvail->P(); int ch = console->RX(); + m_GetChar->V(); return ch; } diff --git a/code/userprog/userthread.cc b/code/userprog/userthread.cc index 6c65d2e..2daf75f 100644 --- a/code/userprog/userthread.cc +++ b/code/userprog/userthread.cc @@ -3,9 +3,56 @@ #include "system.h" #include "userthread.h" #include "syscall.h" +#include "addrspace.h" + + +static void StartUserThread( void * args ){ + + DEBUG('x', "Enter StartUserThread function\n"); + // retrieve function and arguments + // create a ThreadArgs_t struct and cast args content into it + // because we only have a void in our function definition + ThreadArgs_t * cpy_args; + cpy_args = (ThreadArgs_t *) args; + int stack_addr = currentThread->space->AllocateUserStack(); + + // init register + for (int i = 0; i < NumTotalRegs; i++ ) { + machine->WriteRegister(i, 0); + } + + // init Program counter and Next Program Counter registers + machine->WriteRegister(PCReg, cpy_args->f); + machine->WriteRegister (NextPCReg, machine->ReadRegister(PCReg) + 4); + DEBUG('x',"PCReg: 0x%x, NextPCReg: 0x%x\n", cpy_args->f, cpy_args->f + 4); + + // init register 4: arguments + machine->WriteRegister(4, cpy_args->arg); + DEBUG('x',"Register 4: 0x%x\n", cpy_args->arg); + + // init stack + machine->WriteRegister(StackReg, stack_addr); + DEBUG('x',"StackRegister: 0x%x\n", stack_addr); + + // run our thread + machine->Run(); +} int do_ThreadCreate(int f, int arg){ + DEBUG('x',"Enter do_ThreadCreate function\n"); + + // Initialize our structure we'll pass to StartUserThread + ThreadArgs_t * args = (ThreadArgs_t *) malloc(sizeof(ThreadArgs_t)); + args->f = f; + args->arg = arg; + + // create a new Thread and start it + Thread * newThread = new Thread("new thread"); + newThread->space = currentThread->space; + newThread->Start(StartUserThread, args); + + return 0; } void do_ThreadExit(){ diff --git a/code/userprog/userthread.h b/code/userprog/userthread.h index 7051d3c..7510d4c 100644 --- a/code/userprog/userthread.h +++ b/code/userprog/userthread.h @@ -2,6 +2,12 @@ #include "copyright.h" #include "utility.h" + +typedef struct { + int f; + int arg; +} ThreadArgs_t; + extern int do_ThreadCreate(int f, int arg); extern void do_ThreadExit(); #endif