diff --git a/code/test/threadcreate.c b/code/test/threadcreate.c index 9861c8b..7e57fe8 100644 --- a/code/test/threadcreate.c +++ b/code/test/threadcreate.c @@ -6,15 +6,15 @@ void f(int c) { * a problem here, when executing a thread there is not 8 iterations. * This is like synchronisation */ volatile int i; - for (i=0;i<8;i++){ + for (i=0;i<16;i++){ PutChar((char)c); } ThreadExit(); } int main(){ - int i = 64; - for (i=64; i < 68; i++){ + int i; + for (i=65; i < 91; i++){ ThreadCreate(f, i); } // PutString("end of main()\n"); diff --git a/code/userprog/addrspace.cc b/code/userprog/addrspace.cc index 2aed310..fee6ced 100644 --- a/code/userprog/addrspace.cc +++ b/code/userprog/addrspace.cc @@ -21,7 +21,10 @@ #include "noff.h" #include "syscall.h" #include "new" - +#ifdef CHANGED +#include "synch.h" +#include "bitmap.h" +#endif //CHANGED //---------------------------------------------------------------------- // SwapHeader // Do little endian to big endian conversion on the bytes in the @@ -129,8 +132,17 @@ AddrSpace::AddrSpace (OpenFile * executable) pageTable[0].valid = FALSE; // Catch NULL dereference #ifdef CHANGED + int bitmapSize = UserStacksAreaSize / UserStackSize; DEBUG('x', "Initialise thread counter\n"); - Threads = 1; + threads = 1; + + DEBUG('x', "Initialise semaphores\n"); + semThreadsCounter = new Semaphore("AddrSpace_thread_counter", 1); + semAllocateUserStack = new Semaphore("Stack Avaiable", 1); + + DEBUG('x', "Initialize memory map size:%d", bitmapSize); + memoryMap = new BitMap(bitmapSize); + memoryMap->Mark(0); #endif //CHANGED AddrSpaceList.Append(this); @@ -147,6 +159,11 @@ AddrSpace::~AddrSpace () pageTable = NULL; AddrSpaceList.Remove(this); + #ifdef CHANGED + delete semThreadsCounter; + delete semAllocateUserStack; + delete memoryMap; + #endif } //---------------------------------------------------------------------- @@ -303,6 +320,25 @@ int AddrSpace::AllocateUserStack() { int memory = numPages * PageSize; - return memory - 256; + int bit; + + /* If we don't have any free slot, we can wait for one to be + * freed by DeAllocateUserstack + */ + while ((bit = memoryMap->Find()) == - 1){ + DEBUG('x', "Can't allocate User Stack Wainting...\n"); + semAllocateUserStack->P(); + } + int addr = memory - UserStackSize * bit; + DEBUG('x', "Allocate User Stack bit %d, addr:%x\n", bit, addr); + return addr; +} +void +AddrSpace::DeAllocateUserStack(int addr){ + int memory = numPages * PageSize; + int bit = (memory - addr) / UserStackSize; + DEBUG('x', "Deallocate User Stack bit %d, addr:%x\n", bit, addr); + memoryMap->Clear(bit); + semAllocateUserStack->V(); } #endif diff --git a/code/userprog/addrspace.h b/code/userprog/addrspace.h index bd44fdd..617b37a 100644 --- a/code/userprog/addrspace.h +++ b/code/userprog/addrspace.h @@ -19,6 +19,13 @@ #include "noff.h" #include "list.h" + +#ifdef CHANGED +#include "bitmap.h" +class Semaphore; +#define UserStackSize 256 +#endif //CHANGED + #define UserStacksAreaSize 1024 // increase this as necessary! class AddrSpace:public dontcopythis @@ -41,8 +48,12 @@ class AddrSpace:public dontcopythis // Dump program layout as SVG unsigned NumPages() { return numPages; } #ifdef CHANGED - int Threads; // count number of threads into address space + int threads; // count number of threads into address space + Semaphore * semThreadsCounter; + Semaphore * semAllocateUserStack; + BitMap * memoryMap; int AllocateUserStack(); + void DeAllocateUserStack(int addr); #endif private: NoffHeader noffH; // Program layout diff --git a/code/userprog/userthread.cc b/code/userprog/userthread.cc index da97ea0..f1b0aa2 100644 --- a/code/userprog/userthread.cc +++ b/code/userprog/userthread.cc @@ -4,6 +4,7 @@ #include "userthread.h" #include "syscall.h" #include "addrspace.h" +#include "synch.h" static void StartUserThread( void * args ){ @@ -55,8 +56,10 @@ int do_ThreadCreate(int f, int arg){ Thread * newThread = new Thread("new thread"); // increment number of threads - currentThread->space->Threads++; - DEBUG('x', "Increase numbers of Threads:%d\n",currentThread->space->Threads); + currentThread->space->semThreadsCounter->P(); + currentThread->space->threads++; + currentThread->space->semThreadsCounter->V(); + DEBUG('x', "Increase numbers of Threads:%d\n",currentThread->space->threads); newThread->space = currentThread->space; newThread->Start(StartUserThread, args); @@ -69,8 +72,14 @@ void do_ThreadExit(){ // TODO: what should we do with thread space? // Probalely desallocate it... if no threads remain // currentThread->space->Threads--; - DEBUG('x', "Decrease numbers of Threads:%d\n",currentThread->space->Threads); - if ( --currentThread->space->Threads == 0){ + currentThread->space->semThreadsCounter->P(); + currentThread->space->threads--; + currentThread->space->semThreadsCounter->V(); + int addr = machine->ReadRegister(StackReg); + currentThread->space->DeAllocateUserStack(addr); + DEBUG('x', "Decrease numbers of Threads:%d\n",currentThread->space->threads); + + if ( currentThread->space->threads == 0 ){ // No threads remains, desallocate addrspace delete currentThread->space; interrupt->Powerdown();