Presentation is loading. Please wait.

Presentation is loading. Please wait.

NachOS Threads System Road Map through the Code Lab 3.

Similar presentations


Presentation on theme: "NachOS Threads System Road Map through the Code Lab 3."— Presentation transcript:

1 NachOS Threads System Road Map through the Code Lab 3

2 ./threads Directory Files copyright.hscheduler.ccsynch.cc system.ccthreadtest.cclist.cc scheduler.hsynch.hsystem.h utility.cclist.hswitch.h synchlist.ccthread.ccutility.h main.ccswitch.ssynchlist.h thread.h

3 Important Classes Thread : resembles PCB that contains info about the thread, status and registers. List : a simple linked list with elements that points to void*, thus it can contain any element type (in our case it will be Thread ). Scheduler : contains the ready queue which is an instance of the List class.

4 Important Classes Interrupt : the interrupt vector (interrupt status). Statistics : the object that will collect statistics about the system operations. Timer : resembles the hardware timer (in this lab you will implement the alarm clock class from it).

5 Important Objects NachOS –specifically threads lab- contain some important global objects. These objects are defined to be extern. extern objects are accessible from all places in the program. They are made extern so that they will be dealt as a container.

6 Important Objects These objects are defined in the system.cc file, and to use them you have include system.h file in each file that uses these objects. These objects are defined as pointers to objects not as regular objects.

7 Important Objects extern Thread * currentThread; extern Thread * threadToBeDestroyed; extern Scheduler * scheduler; extern Interrupt * interrupt; extern Statistics * stats; extern Timer * timer; The file also contains other objects that may be instantiated if you are working on other labs. An important something that has to be noticed that thread systems (source code) lab is used in other labs, i.e. in the multiprogramming lab.

8 currentThread Object It points to the thread that is grabbing the CPU now. This thread is out of the ready queue. Its status is RUNNING.

9 threadToBeDestroyed Object It points to the thread that is to be destroyed after calling the Finish method on that thread object. Its status is BLOCKED. Initially it is pointing to NULL.

10 scheduler Object It points to the scheduler object. Contains the ready queue. Its function members represents the scheduling algorithm that is used (now it is FCFS).

11 interrupt Object interrupt This pointer points to the interrupt vector of the processor. It will be always turned off whenever the kernel is taking the control of the processor, i.e. in the case of context switching.

12 stats + timer Object stats : This pointer points to an object of type Statistics, this object will store some statistical information about the operation of the system such as the number of characters read or sent by a socket. timer :resembles the hardware of timer.

13 Class Thread Important Public Members: –Thread (char * name); –~Thread(); –void Yield(); –void Sleep(); –void Finish(); –void CheckOverflow(); –void setStatus();

14 Class Thread Important Private Members: –int * stackTop; –int * stack; –int machineState[machineStateSize]; –ThreadStatus status; –char * name; –// some members if running user programs –AddressSpace * space; –int userResgisters[NumTotalRegs]; –Void SaveUserState(); –Void RestoreUserSpace();

15 Class Thread One must be aware of the difference between: –Process and a Thread. –Thread scheduling and Process scheduling. –Context switching of a Threads and Context switching of a Processes.

16 Thread::Thread(char * name) Initialize the thread name. Set its state to JUST_CREATED ; Thread::~Thread() Deallocate the initialized stack.

17 Thread::Fork(VoidFunctionPtr, int arg) Allocate the stack for the thread. If we are running a user process we have to allocate an address space for the process and registers to be used by the kernel. Set its state to READY. Put this thread on the rear of the ready queue.

18 Thread::Yield() Find next thread to allocate the CPU for it. Put the currentThread on the rear of the ready queue. Initiates the current thread to run

19 Thread::CheckOverFlow() After doing context switching it is preferable to check if the stack overflowed or not. The stackSize is defined to be 1024 * 4 bytes. If there is an overflow an ASSERT – assertion failure- will occur. If this happens just increase the stackSize to a greater integer.

20 Thread::Finish() Set the pointer thradToBeDestroyed to the calling thread. Call Sleep() method.

21 Thread::Sleep() Set the state of the thread to BLOCKED. Find the next thread from the ready queue and initiates it to run.

22 Class Scheduler Important Public Members: –Scheduler(); –~ Scheduler(); –void ReadyToRun(Thread * thread); –Thread * FindNextToRun(); –void Run(); –void Print();

23 Class Scheduler Important Private Members: –List * readyList;

24 Scheduler::Scheduler() Constructor create a pointer to readyList via new operator. Scheduler::~Scheduler() Destructor delete the pointer readyList via delete operator.

25 void Scheduler::ReadyToRun(Thread * thread) Make the thread state to READY. Append the thread to the rear of the ready queue Thread * Scheduler::FindNextToRun() Returns a pointer to the thread at the head of the ready queue after removing it from the queue.

26 void Scheduler::Run(Thread * nextThread) Do the context switching between the currentThread and nextThread. Then it will check for overflow. Set the state of the currentThread to RUNNING. If we running a user thread we have ti save the user space

27 Class Interupt One method of class Interrupt is important to know: –IntSatus Interrpt::SetLevel(IntSatus satus ); This method set the interrupt vector to the status value and returns the old value of the vector. There is an enum data type IntOff that turns off all interrupts.

28 NachOS code execution main.cc # include “system.h”

29 NachOS code execution main.cc # include “system.h”

30 NachOS code execution main.cc # include “system.h” system.cc Thread * currentThread; Thread * threadToBeDestroyed; Scheduler * scheduler; Interrupt * interrupt; Statistics * stats; Timer * timer;

31 NachOS code execution main.cc # include “system.h” system.cc Thread * currentThread; Thread * threadToBeDestroyed; Scheduler * scheduler; Interrupt * interrupt; Statistics * stats; Timer * timer;

32 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); system.cc Thread * currentThread; Thread * threadToBeDestroyed; Scheduler * scheduler; Interrupt * interrupt; Statistics * stats; Timer * timer;

33 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); system.cc void Initialize(int argc, char ** argv) { // execute some parsing code // to get the debug flags DebugInit (debugArgs); stats = new Statistics(); interrupt = new Interrupt(); acheduler = new Scheduler(); If (some condition in debug flags) timer = new Timer(); currentThread = new Thread(“main”); currentThread->setStatus(RUNNING); interrupt->Enable(); }

34 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); system.cc void Initialize(int argc, char ** argv) { // execute some parsing code // to get the debug flags DebugInit (debugArgs); Stats = new Statistics(); Interrupt = new Interrupt(); Scheduler = new Scheduler(); If (some condition in debug flags) timer = new Timer(); currentThread = new Thread(“main”); currentThread->setStatus(RUNNING); interrupt->Enable(); } This will create a thread named “main”

35 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); system.cc void Initialize(int argc, char ** argv) { // execute some parsing code // to get the debug flags DebugInit (debugArgs); Stats = new Statistics(); Interrupt = new Interrupt(); Scheduler = new Scheduler(); If (some condition in debug flags) timer = new Timer(); currentThread = new Thread(“main”); currentThread->setStatus(RUNNING); interrupt->Enable(); }

36 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

37 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); } This will create a thread named “forked thread”

38 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); } 1- This will allocate a stack for this thread by executing SimpleThread function and passing 1 as a parameter to the function. 2- Put t thread on the ready queue. 3- set its status to READY.

39 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); } This will execute SimpleThread in the thread main with an argument of 0

40 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

41 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

42 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

43 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

44 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt- >SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } Thread * Scheduler::FindNextToRun() { return (Thread *)readyList->Remove(); } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

45 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt- >SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } Thread * Scheduler::FindNextToRun() { return (Thread *)readyList->Remove(); } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

46 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt- >SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } Thread * Scheduler::FindNextToRun() { return (Thread *)readyList->Remove(); } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

47 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt- >SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } void Scheduler::ReadyToRun(Thread * thread) { thread->setStatus(READY); readyList->Append((void *)thread); } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

48 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt- >SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } void Scheduler::ReadyToRun(Thread * thread) { thread->setStatus(READY); readyList->Append((void *)thread); } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

49 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt->SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } void Scheduler::Run(Thread * nextThread) { Thread * oldThread = currentThread; // save status if using another user program oldThread->CheckOverflow(); currentThread = nextThread; currentThread->setStatus(RUNNING); SWITCH(oldThread,nextThread); // this will do CS if (threadToBeDestroyed!=NULL) { delete threadToBeDestroyed; threadToBeDestroyed = NULL; } // restore new thread space if using another user // program } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

50 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt->SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } void Scheduler::Run(Thread * nextThread) { Thread * oldThread = currentThread; // save status if using another user program oldThread->CheckOverflow(); currentThread = nextThread; currentThread->setStatus(RUNNING); SWITCH(oldThread,nextThread); // this will do CS if (threadToBeDestroyed!=NULL) { delete threadToBeDestroyed; threadToBeDestroyed = NULL; } // restore new thread space if using another user // program } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

51 NachOS code execution thread.cc void Thread::Yield() { Thread * nextThread; IntStatus oldState = interrupt->SetLevel(IntOff); nextThread = scheduler->FindNextToRun(); if(nextThread!=NULL) { scheduler->ReadyToRun(this); scheduler->Run(nextThread); } interrupt->SetLevel(oldStatus); } void Scheduler::Run(Thread * nextThread) { Thread * oldThread = currentThread; // save status if using another user program oldThread->CheckOverflow(); currentThread = nextThread; currentThread->setStatus(RUNNING); SWITCH(oldThread,nextThread); // this will do CS if (threadToBeDestroyed!=NULL) { delete threadToBeDestroyed; threadToBeDestroyed = NULL; } // restore new thread space if using another user // program } threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

52 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); } Now start executing in the thread “forked thread” at the start of the function (the value of that thread PC)

53 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); } Keep on this tone until thread “main” reaches num=5 then it will exits SimpleTest function and returb to the main function

54 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest();. currentThread->Finish(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

55 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest();. currentThread->Finish(); threadtest.cc void SimpleThread(int which) { for(num=0;num<5;++num) { printf(“*** thread %d looped %d times\n”,which,num); currentThread->Yield(); } void ThreadTest() { Thread * t = new Thread(“forked thread”); t->Fork(SimpleThread,1); SimpleThread(0); }

56 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest();. currentThread->Finish(); thread.cc void Thread::Finish() { interrupt->SetLevel(IntOff); threadToBeDestroyed = currentThread; Sleep(); } Void Thread::Sleep() { Thread * nextThread; status = BLOCKED; while (( nextThread=scheduler->FindNextToRun())==NULL ) interrupt->Idle(); scheduler->Run(nextThread); }

57 NachOS code execution main.cc # include “system.h” Initialize(argc,argv); ThreadTest();. currentThread->Finish(); thread.cc void Thread::Finish() { interrupt->SetLevel(IntOff); threadToBeDestroyed = currentThread; Sleep(); } Void Thread::Sleep() { Thread * nextThread; status = BLOCKED; while (( nextThread=scheduler->FindNextToRun())==NULL ) interrupt->Idle(); scheduler->Run(nextThread); }

58 NachOS code execution scheduler.cc void Scheduler::Run(Thread * nextThread) { Thread * oldThread = currentThread; // save status if using another user program oldThread->CheckOverflow(); currentThread = nextThread; currentThread->setStatus(RUNNING); SWITCH(oldThread,nextThread); // this will // do CS if (threadToBeDestroyed!=NULL) { delete threadToBeDestroyed; threadToBeDestroyed = NULL; } // restore new thread space if using another user // program } thread.cc void Thread::Finish() { interrupt->SetLevel(IntOff); threadToBeDestroyed = currentThread; Sleep(); } Void Thread::Sleep() { Thread * nextThread; status = BLOCKED; while (( nextThread=scheduler->FindNextToRun())==NULL ) interrupt->Idle(); scheduler->Run(nextThread); }

59 NachOS code execution scheduler.cc void Scheduler::Run(Thread * nextThread) { Thread * oldThread = currentThread; // save status if using another user program oldThread->CheckOverflow(); currentThread = nextThread; currentThread->setStatus(RUNNING); SWITCH(oldThread,nextThread); // this will // do CS if (threadToBeDestroyed!=NULL) { delete threadToBeDestroyed; threadToBeDestroyed = NULL; } // restore new thread space if using another user // program } thread.cc void Thread::Finish() { interrupt->SetLevel(IntOff); threadToBeDestroyed = currentThread; Sleep(); } Void Thread::Sleep() { Thread * nextThread; status = BLOCKED; while (( nextThread=scheduler->FindNextToRun())==NULL ) interrupt->Idle(); scheduler->Run(nextThread); } At this point “forked thread” finds that it has reached at the end of its program so it returns the control to the kernel which will be the scheduler

60 Assignment # 3 In the assignment you are required to solve questions 1,2,4,8 and 10 from the assignment posted on the website. The assignment is due to next Thursday 6/5/2004.


Download ppt "NachOS Threads System Road Map through the Code Lab 3."

Similar presentations


Ads by Google