#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