TD2 II.3-4 Manage UserStack with Bitmap

Add a Semaphore to manage threads waiting list
This commit is contained in:
Yorick Barbanneau 2021-11-18 23:12:42 +01:00
parent 6e0d91918a
commit 4da093ca38
4 changed files with 67 additions and 11 deletions

View file

@ -6,15 +6,15 @@ void f(int c) {
* a problem here, when executing a thread there is not 8 iterations. * a problem here, when executing a thread there is not 8 iterations.
* This is like synchronisation */ * This is like synchronisation */
volatile int i; volatile int i;
for (i=0;i<8;i++){ for (i=0;i<16;i++){
PutChar((char)c); PutChar((char)c);
} }
ThreadExit(); ThreadExit();
} }
int main(){ int main(){
int i = 64; int i;
for (i=64; i < 68; i++){ for (i=65; i < 91; i++){
ThreadCreate(f, i); ThreadCreate(f, i);
} }
// PutString("end of main()\n"); // PutString("end of main()\n");

View file

@ -21,7 +21,10 @@
#include "noff.h" #include "noff.h"
#include "syscall.h" #include "syscall.h"
#include "new" #include "new"
#ifdef CHANGED
#include "synch.h"
#include "bitmap.h"
#endif //CHANGED
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// SwapHeader // SwapHeader
// Do little endian to big endian conversion on the bytes in the // 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 pageTable[0].valid = FALSE; // Catch NULL dereference
#ifdef CHANGED #ifdef CHANGED
int bitmapSize = UserStacksAreaSize / UserStackSize;
DEBUG('x', "Initialise thread counter\n"); 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 #endif //CHANGED
AddrSpaceList.Append(this); AddrSpaceList.Append(this);
@ -147,6 +159,11 @@ AddrSpace::~AddrSpace ()
pageTable = NULL; pageTable = NULL;
AddrSpaceList.Remove(this); AddrSpaceList.Remove(this);
#ifdef CHANGED
delete semThreadsCounter;
delete semAllocateUserStack;
delete memoryMap;
#endif
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -303,6 +320,25 @@ int
AddrSpace::AllocateUserStack() AddrSpace::AllocateUserStack()
{ {
int memory = numPages * PageSize; 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 #endif

View file

@ -19,6 +19,13 @@
#include "noff.h" #include "noff.h"
#include "list.h" #include "list.h"
#ifdef CHANGED
#include "bitmap.h"
class Semaphore;
#define UserStackSize 256
#endif //CHANGED
#define UserStacksAreaSize 1024 // increase this as necessary! #define UserStacksAreaSize 1024 // increase this as necessary!
class AddrSpace:public dontcopythis class AddrSpace:public dontcopythis
@ -41,8 +48,12 @@ class AddrSpace:public dontcopythis
// Dump program layout as SVG // Dump program layout as SVG
unsigned NumPages() { return numPages; } unsigned NumPages() { return numPages; }
#ifdef CHANGED #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(); int AllocateUserStack();
void DeAllocateUserStack(int addr);
#endif #endif
private: private:
NoffHeader noffH; // Program layout NoffHeader noffH; // Program layout

View file

@ -4,6 +4,7 @@
#include "userthread.h" #include "userthread.h"
#include "syscall.h" #include "syscall.h"
#include "addrspace.h" #include "addrspace.h"
#include "synch.h"
static void StartUserThread( void * args ){ static void StartUserThread( void * args ){
@ -55,8 +56,10 @@ int do_ThreadCreate(int f, int arg){
Thread * newThread = new Thread("new thread"); Thread * newThread = new Thread("new thread");
// increment number of threads // increment number of threads
currentThread->space->Threads++; currentThread->space->semThreadsCounter->P();
DEBUG('x', "Increase numbers of Threads:%d\n",currentThread->space->Threads); currentThread->space->threads++;
currentThread->space->semThreadsCounter->V();
DEBUG('x', "Increase numbers of Threads:%d\n",currentThread->space->threads);
newThread->space = currentThread->space; newThread->space = currentThread->space;
newThread->Start(StartUserThread, args); newThread->Start(StartUserThread, args);
@ -69,8 +72,14 @@ void do_ThreadExit(){
// TODO: what should we do with thread space? // TODO: what should we do with thread space?
// Probalely desallocate it... if no threads remain // Probalely desallocate it... if no threads remain
// currentThread->space->Threads--; // currentThread->space->Threads--;
DEBUG('x', "Decrease numbers of Threads:%d\n",currentThread->space->Threads); currentThread->space->semThreadsCounter->P();
if ( --currentThread->space->Threads == 0){ 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 // No threads remains, desallocate addrspace
delete currentThread->space; delete currentThread->space;
interrupt->Powerdown(); interrupt->Powerdown();