NachOS/code/userprog/userthread.cc
Yorick Barbanneau 4da093ca38 TD2 II.3-4 Manage UserStack with Bitmap
Add a Semaphore to manage threads waiting list
2021-11-19 14:15:58 +01:00

89 lines
2.7 KiB
C++

#ifdef CHANGED
#include "copyright.h"
#include "system.h"
#include "userthread.h"
#include "syscall.h"
#include "addrspace.h"
#include "synch.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);
// All our registers have values, we can desallocate our cpy_args
free(cpy_args);
cpy_args = NULL;
// 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");
// increment number of 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);
return 0;
}
void do_ThreadExit(){
DEBUG('x', "Enter do_ThreadExit function\n");
// TODO: what should we do with thread space?
// Probalely desallocate it... if no threads remain
// currentThread->space->Threads--;
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();
}
currentThread->Finish();
}
#endif