TD2 II.3-4 Manage UserStack with Bitmap
Add a Semaphore to manage threads waiting list
This commit is contained in:
parent
6e0d91918a
commit
4da093ca38
4 changed files with 67 additions and 11 deletions
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue