TD2 I.5 first working version of Thread
Add semaphore to PutChar and GetChar
This commit is contained in:
parent
c4a2d25163
commit
6bd3e1338f
8 changed files with 95 additions and 4 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -16,5 +16,6 @@ code/test/putint
|
||||||
code/test/putstring
|
code/test/putstring
|
||||||
code/test/shell
|
code/test/shell
|
||||||
code/test/sort
|
code/test/sort
|
||||||
|
code/test/threadcreate
|
||||||
code/threads/nachos
|
code/threads/nachos
|
||||||
code/userprog/nachos
|
code/userprog/nachos
|
||||||
|
|
|
@ -41,8 +41,8 @@ CFLAGS += -fsanitize=undefined
|
||||||
LDFLAGS += -fsanitize=undefined
|
LDFLAGS += -fsanitize=undefined
|
||||||
|
|
||||||
# décommenté TD1 - partie V
|
# décommenté TD1 - partie V
|
||||||
CFLAGS += -fsanitize=address
|
#CFLAGS += -fsanitize=address
|
||||||
LDFLAGS += -fsanitize=address -lpthread
|
#LDFLAGS += -fsanitize=address -lpthread
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(NACHOS_SYS),MAC_OS_SYS)
|
ifeq ($(NACHOS_SYS),MAC_OS_SYS)
|
||||||
|
|
13
code/test/threadcreate.c
Normal file
13
code/test/threadcreate.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifdef CHANGED
|
||||||
|
#include "syscall.h"
|
||||||
|
|
||||||
|
void f(int c) {
|
||||||
|
PutString("Thead!");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
//int i;
|
||||||
|
ThreadCreate(f, 66);
|
||||||
|
PutString("end of main()\n");
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -292,3 +292,12 @@ AddrSpace::RestoreState ()
|
||||||
machine->currentPageTable = pageTable;
|
machine->currentPageTable = pageTable;
|
||||||
machine->currentPageTableSize = numPages;
|
machine->currentPageTableSize = numPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CHANGED
|
||||||
|
int
|
||||||
|
AddrSpace::AllocateUserStack()
|
||||||
|
{
|
||||||
|
int memory = numPages * PageSize;
|
||||||
|
return memory - 256;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -40,7 +40,9 @@ class AddrSpace:public dontcopythis
|
||||||
unsigned blocksize);
|
unsigned blocksize);
|
||||||
// Dump program layout as SVG
|
// Dump program layout as SVG
|
||||||
unsigned NumPages() { return numPages; }
|
unsigned NumPages() { return numPages; }
|
||||||
|
#ifdef CHANGED
|
||||||
|
int AllocateUserStack();
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
NoffHeader noffH; // Program layout
|
NoffHeader noffH; // Program layout
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
static Semaphore *readAvail;
|
static Semaphore *readAvail;
|
||||||
static Semaphore *writeDone;
|
static Semaphore *writeDone;
|
||||||
|
static Semaphore *m_PutChar;
|
||||||
|
static Semaphore *m_GetChar;
|
||||||
|
|
||||||
static void ReadAvailHandler(void *arg) { (void) arg; readAvail->V(); }
|
static void ReadAvailHandler(void *arg) { (void) arg; readAvail->V(); }
|
||||||
static void WriteDoneHandler(void *arg) { (void) arg; writeDone->V(); }
|
static void WriteDoneHandler(void *arg) { (void) arg; writeDone->V(); }
|
||||||
|
@ -15,6 +17,11 @@ ConsoleDriver::ConsoleDriver(const char *in, const char *out)
|
||||||
readAvail = new Semaphore("read avail", 0);
|
readAvail = new Semaphore("read avail", 0);
|
||||||
writeDone = new Semaphore("write done", 0);
|
writeDone = new Semaphore("write done", 0);
|
||||||
console = new Console (in, out, ReadAvailHandler, WriteDoneHandler, NULL);
|
console = new Console (in, out, ReadAvailHandler, WriteDoneHandler, NULL);
|
||||||
|
|
||||||
|
// Add these semaphores because we had problems with threads
|
||||||
|
// Assert error on putBusy
|
||||||
|
m_PutChar = new Semaphore("PutChar", 1);
|
||||||
|
m_GetChar = new Semaphore("GetChar", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleDriver::~ConsoleDriver()
|
ConsoleDriver::~ConsoleDriver()
|
||||||
|
@ -22,18 +29,24 @@ ConsoleDriver::~ConsoleDriver()
|
||||||
delete console;
|
delete console;
|
||||||
delete writeDone;
|
delete writeDone;
|
||||||
delete readAvail;
|
delete readAvail;
|
||||||
|
delete m_PutChar;
|
||||||
|
delete m_GetChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDriver::PutChar( int ch)
|
void ConsoleDriver::PutChar( int ch)
|
||||||
{
|
{
|
||||||
|
m_PutChar->P();
|
||||||
console->TX(ch);
|
console->TX(ch);
|
||||||
writeDone->P();
|
writeDone->P();
|
||||||
|
m_PutChar->V();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConsoleDriver::GetChar()
|
int ConsoleDriver::GetChar()
|
||||||
{
|
{
|
||||||
|
m_GetChar->P();
|
||||||
readAvail->P();
|
readAvail->P();
|
||||||
int ch = console->RX();
|
int ch = console->RX();
|
||||||
|
m_GetChar->V();
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,56 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "userthread.h"
|
#include "userthread.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#include "addrspace.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);
|
||||||
|
|
||||||
|
// run our thread
|
||||||
|
machine->Run();
|
||||||
|
}
|
||||||
|
|
||||||
int do_ThreadCreate(int f, int arg){
|
int do_ThreadCreate(int f, int arg){
|
||||||
|
|
||||||
DEBUG('x',"Enter do_ThreadCreate function\n");
|
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");
|
||||||
|
newThread->space = currentThread->space;
|
||||||
|
newThread->Start(StartUserThread, args);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_ThreadExit(){
|
void do_ThreadExit(){
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
#include "copyright.h"
|
#include "copyright.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int f;
|
||||||
|
int arg;
|
||||||
|
} ThreadArgs_t;
|
||||||
|
|
||||||
extern int do_ThreadCreate(int f, int arg);
|
extern int do_ThreadCreate(int f, int arg);
|
||||||
extern void do_ThreadExit();
|
extern void do_ThreadExit();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue