135 lines
3.8 KiB
C++
135 lines
3.8 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;
|
|
|
|
// 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, cpy_args->stackAddr);
|
|
DEBUG('x',"StackRegister: 0x%x\n", cpy_args->stackAddr);
|
|
|
|
// 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;
|
|
|
|
// Check if we can allocate Stack for our son
|
|
args->stackAddr = currentThread->space->AllocateUserStack();
|
|
if ( args->stackAddr == -1 ) {
|
|
fprintf(stderr, "Stack Overflow\n");
|
|
Exit(1);
|
|
}
|
|
DEBUG('x',"Father found stack address: 0x%x\n", args->stackAddr);
|
|
// 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 ){
|
|
DEBUG('x', "Delete Userspace, no more Threads\n");
|
|
// No threads remains, desallocate addrspace
|
|
delete currentThread->space;
|
|
currentThread->space = NULL;
|
|
}
|
|
|
|
currentThread->Finish();
|
|
DEBUG('x', "Thread killed!\n");
|
|
}
|
|
|
|
void StartUserProc( void * args ){
|
|
currentThread->space->InitRegisters();
|
|
currentThread->space->RestoreState();
|
|
//machine->DumpMem("memory.svg");
|
|
machine->Run();
|
|
}
|
|
|
|
int do_ForkExec( const char * c){
|
|
DEBUG('x', "Enter ForkExec\n");
|
|
AddrSpace * space;
|
|
Thread * fork;
|
|
OpenFile * file;
|
|
|
|
file = fileSystem->Open(c);
|
|
|
|
if (file == NULL) {
|
|
printf("Unable to open file %s\n", c);
|
|
return -1;
|
|
}
|
|
|
|
try {
|
|
space = new AddrSpace(file);
|
|
}catch(const std::bad_alloc& e) {
|
|
fprintf(stderr,"Could not allocate Memory\n");
|
|
Exit(1);
|
|
}
|
|
|
|
fork = new Thread("forkThread");
|
|
fork->space = space;
|
|
fork->Start(StartUserProc, NULL);
|
|
|
|
delete file;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif
|