brickos scheduling solving the low-priority starvation problem

26
BrickOS Scheduling BrickOS Scheduling Solving The Low-Priority Solving The Low-Priority Starvation Problem Starvation Problem

Upload: lynne-carroll

Post on 25-Dec-2015

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: BrickOS Scheduling Solving The Low-Priority Starvation Problem

BrickOS SchedulingBrickOS Scheduling

Solving The Low-Priority Solving The Low-Priority Starvation ProblemStarvation Problem

Page 2: BrickOS Scheduling Solving The Low-Priority Starvation Problem

IntroductionIntroduction

Jon RogersJon Rogers

Robbie EdwardsRobbie Edwards

Melanie SparksMelanie Sparks

Page 3: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Project DescriptionProject Description

Investigate the way the scheduling Investigate the way the scheduling algorithm is currently implemented. algorithm is currently implemented. Change it so that higher priority processes Change it so that higher priority processes cannot starve the low priority processes.cannot starve the low priority processes.

Page 4: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Project FacetsProject Facets

1 Researching the problem1 Researching the problem

2 Defining a solution2 Defining a solution

3 Building a development environment3 Building a development environment

4 Modifying the source code4 Modifying the source code

5 Testing and verification5 Testing and verification

Page 5: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Researching The ProblemResearching The Problem

Research the operating system schedulerResearch the operating system scheduler

Identify the relevant source codeIdentify the relevant source code

Determine the current scheduling Determine the current scheduling implementation implementation

Page 6: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Researching The Problem - Researching The Problem - ResultsResults

BrickOS employs a preemptive scheduler BrickOS employs a preemptive scheduler with a prioritized round-robin algorithm for with a prioritized round-robin algorithm for choosing the next process to run.choosing the next process to run.

Page 7: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Researching The Problem - Researching The Problem - Detailed ResultsDetailed Results

Each process is given a default time slice Each process is given a default time slice of 20ms to run before being interrupted by of 20ms to run before being interrupted by the OS and another process is allowed to the OS and another process is allowed to runrun

In choosing the next process to run, the In choosing the next process to run, the OS searches through each process OS searches through each process queue, beginning with the highest priority queue, beginning with the highest priority queue, and runs the first READY processqueue, and runs the first READY process

Page 8: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Hence The Problem -Hence The Problem -

If there are always processes of higher If there are always processes of higher priority that are ready to run, lower priority priority that are ready to run, lower priority processes will be starved outprocesses will be starved out

Page 9: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Defining A SolutionDefining A Solution

The Challenge: to prevent starvation while The Challenge: to prevent starvation while preserving process prioritypreserving process priorityThe Solution: Chain Wait, another The Solution: Chain Wait, another selection parameterselection parameterChain Wait will numerically represent the Chain Wait will numerically represent the maximum number of scheduler executions maximum number of scheduler executions for which a particular priority chain will be for which a particular priority chain will be exempt (e.g. no processes from this exempt (e.g. no processes from this priority chain will be chosen: waiting)priority chain will be chosen: waiting)

Page 10: BrickOS Scheduling Solving The Low-Priority Starvation Problem

The AlgorithmThe Algorithm

Initialization: All chain wait values will be set Initialization: All chain wait values will be set to zeroto zero

Scheduler will do a linear search through the Scheduler will do a linear search through the priority chains for runnable processespriority chains for runnable processes

Upon running a process, the chain wait for Upon running a process, the chain wait for its priority queue will be set to 20-P+1, its priority queue will be set to 20-P+1, where P is the numeric priority and where P is the numeric priority and scheduler will resume its linear searchscheduler will resume its linear search

Page 11: BrickOS Scheduling Solving The Low-Priority Starvation Problem

The AlgorithmThe Algorithm

For each priority queue with a chain wait For each priority queue with a chain wait greater than zero, decrement the chain greater than zero, decrement the chain wait and move to the next queue ignoring wait and move to the next queue ignoring ready processes from this queueready processes from this queue

If the linear search is complete and no If the linear search is complete and no runnable processes are found, all chain runnable processes are found, all chain waits are reset to 0waits are reset to 0

Page 12: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Building A Development Building A Development EnvironmentEnvironment

Installation of Cygwin on the target Windows Installation of Cygwin on the target Windows machinemachineBuilding the Hitachi-H8 cross-compiler : a trivial Building the Hitachi-H8 cross-compiler : a trivial initialization followed by a very long compile initialization followed by a very long compile processprocessInstalling BrickOSInstalling BrickOSInstalling the USB tower and driversInstalling the USB tower and driversTesting the environment : Testing the environment :

Hello World and Play Song Hello World and Play Song Testing the environment, part II : creating a test Testing the environment, part II : creating a test program that counts down and plays a songprogram that counts down and plays a song

Page 13: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Changing The Source Code – Changing The Source Code – Additions To tm.hAdditions To tm.h

Implementation begins with adding a new function, Implementation begins with adding a new function, "tm_clear_waits()", that will (as advertised) clear the chain "tm_clear_waits()", that will (as advertised) clear the chain waits, resetting them to zero.waits, resetting them to zero.

void tm_clear_waits() {void tm_clear_waits() {pchain_t* priority;pchain_t* priority;priority = priority_head;priority = priority_head;while((int) priority->priority >= PRIO_LOWEST) while((int) priority->priority >= PRIO_LOWEST)

{{priority->chain_wait = 0;priority->chain_wait = 0;priority = priority->next;priority = priority->next;

}}}}

Page 14: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Changing The Source Code – Changing The Source Code – Additions To tm.cAdditions To tm.c

Implementation of the solution continues with the Implementation of the solution continues with the introduction of a new field, an integer "chain_wait", to the introduction of a new field, an integer "chain_wait", to the existing data structure struct _pchain_t, in the tm.h existing data structure struct _pchain_t, in the tm.h header fileheader file

struct _pchain_t {struct _pchain_t {

priority_t priority; // numeric priority levelpriority_t priority; // numeric priority level

struct _pchain_t *next; // lower priority chainstruct _pchain_t *next; // lower priority chain

struct _pchain_t *prev; // higher priority chainstruct _pchain_t *prev; // higher priority chain

struct _tdata_t *ctid; // current task in chainstruct _tdata_t *ctid; // current task in chain

int chain_wait; // # of times to be ignored by schedulerint chain_wait; // # of times to be ignored by scheduler

};};

Page 15: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Changing The Source Code - Changing The Source Code - Changes To tm.c Changes To tm.c

We modified tm.c inside the function "size_t We modified tm.c inside the function "size_t *tm_scheduler(size_t *old_sp)" at the point *tm_scheduler(size_t *old_sp)" at the point where the next process must be chosenwhere the next process must be chosen

This scheduler function is called by the process This scheduler function is called by the process switcher which in turn is called by a yield switcher which in turn is called by a yield functionfunction

Yield is called by an function that becomes a Yield is called by an function that becomes a zombie [through "exit(..)"], when a process has zombie [through "exit(..)"], when a process has used its timeslice [through systime_handler(..)], used its timeslice [through systime_handler(..)], or when a process sleeps [through or when a process sleeps [through wait_event(..)].wait_event(..)].

Page 16: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Original CodeOriginal CodeThe original code, in which we will choose the next process..The original code, in which we will choose the next process..

while(1) {while(1) { if(next->tstate==T_SLEEPING) if(next->tstate==T_SLEEPING) // if the next task is SLEEPING // if the next task is SLEEPING break;break; // we just run it // we just run it if(next->tstate==T_WAITING) {if(next->tstate==T_WAITING) { // if it's WAITING, wake it and run it // if it's WAITING, wake it and run it ...... break;break; }} }} if(next == priority->ctid) {if(next == priority->ctid) { // if done searching this priority queue // if done searching this priority queue ...... priority = priority->next;priority = priority->next; // search the next priority queue// search the next priority queue ...... next=priority->ctid->next;next=priority->ctid->next; // move to the next one in line in that priority// move to the next one in line in that priority } } else next=next->next;else next=next->next; // otherwise we're still searching this queue// otherwise we're still searching this queue }}

Page 17: BrickOS Scheduling Solving The Low-Priority Starvation Problem

New CodeNew Code

Inside the while loop that searches for the next process, the code is Inside the while loop that searches for the next process, the code is modified as follows:modified as follows:

while(1) {while(1) {

if(priority->chain_wait > 0) {if(priority->chain_wait > 0) { // If there is a chain wait for this priority level// If there is a chain wait for this priority level --(priority->chain_wait);--(priority->chain_wait); // then decrement the wait.// then decrement the wait. if(priority->next != NULL) {if(priority->next != NULL) {

if((int) priority->next->priority < PRIO_LOWEST) if((int) priority->next->priority < PRIO_LOWEST)

{{ // If we have ignored the lowest priority // If we have ignored the lowest priority levellevel tm_clear_waits();tm_clear_waits(); // then clear all chain waits and begin the// then clear all chain waits and begin the priority=priority_head;priority=priority_head; // search for a process again at the highest// search for a process again at the highest next=priority->ctid->next;next=priority->ctid->next; // priority level.// priority level.}}

Page 18: BrickOS Scheduling Solving The Low-Priority Starvation Problem

New CodeNew Code

else {else { priority = priority->next; priority = priority->next; // Otherwise, // Otherwise, next = priority->ctid->next; next = priority->ctid->next; }} //search the next priority //search the next priority

level.level.

}}...... // debugging code omitted // debugging code omitted else priority = priority_head;else priority = priority_head;...... }}

Page 19: BrickOS Scheduling Solving The Low-Priority Starvation Problem

New CodeNew Code

else {else {

if(next->tstate==T_SLEEPING)if(next->tstate==T_SLEEPING) // if the next task is SLEEPING,// if the next task is SLEEPING, break;break; // we just run it// we just run it if(next->tstate==T_WAITING) { if(next->tstate==T_WAITING) { // if it's WAITING // if it's WAITING

......

break;break; // wake it and run it// wake it and run it

}} // sound familiar?// sound familiar? }}

... ... // the remainder of the code// the remainder of the code }} // inside the while loop is unmodified// inside the while loop is unmodified

Page 20: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Changing The Source CodeChanging The Source Code

Upon exiting the while loop that selects the next Upon exiting the while loop that selects the next process to run, set the process' priority level's process to run, set the process' priority level's chain wait. chain wait.

priority->chain_wait = ((int) PRIO_HIGHEST - (int) priority->priority) + 1;priority->chain_wait = ((int) PRIO_HIGHEST - (int) priority->priority) + 1;

For example, if PRIO_HIGHEST is 20 and the For example, if PRIO_HIGHEST is 20 and the process to be executed is of priority 10, then the process to be executed is of priority 10, then the chain wait for priority level 10 will be set to (20-chain wait for priority level 10 will be set to (20-10)+1 = 11.10)+1 = 11.

Page 21: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Changing The Source CodeChanging The Source Code

And the last bit of code added, within the And the last bit of code added, within the process "tid_t execi(..)" upon initializing a process "tid_t execi(..)" upon initializing a new priority queue the chain_wait must new priority queue the chain_wait must also be setalso be set

......

newpchain->priority=priority;newpchain->priority=priority;

newpchain->chain_wait = 0; // initialize chain_wait to 0newpchain->chain_wait = 0; // initialize chain_wait to 0

newpchain->ctid=td;newpchain->ctid=td;

......

Page 22: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Testing And VerificationTesting And Verification

Loading the new operating systemLoading the new operating system

Documenting the lack of starvationDocumenting the lack of starvation

Showing that all threads run no matter the Showing that all threads run no matter the prioritypriority

Page 23: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Testing And Verification - CodeTesting And Verification - Code

The test program: gizmo.cThe test program: gizmo.c

pid2=execi(&motor_driver, 0, NULL, 20, pid2=execi(&motor_driver, 0, NULL, 20, DEFAULT_STACK_SIZE);DEFAULT_STACK_SIZE);

pid3=execi(&foo1, 0, NULL, 20, DEFAULT_STACK_SIZE);pid3=execi(&foo1, 0, NULL, 20, DEFAULT_STACK_SIZE);

pid4=execi(&foo2, 0, NULL, 20, DEFAULT_STACK_SIZE); pid4=execi(&foo2, 0, NULL, 20, DEFAULT_STACK_SIZE);

pid5=execi(&foo3, 0, NULL, 10, DEFAULT_STACK_SIZE);pid5=execi(&foo3, 0, NULL, 10, DEFAULT_STACK_SIZE);

Page 24: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Testing And Verification - CodeTesting And Verification - Code

In the old brickOS, this process would have In the old brickOS, this process would have been starved out. But not in ours.been starved out. But not in ours.

pid6=execi(&playSong, 0, NULL, 1, pid6=execi(&playSong, 0, NULL, 1, DEFAULT_STACK_SIZE);DEFAULT_STACK_SIZE);

You know the scheduler is working correctly You know the scheduler is working correctly when you hear the song playing.when you hear the song playing.

Page 25: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Testing And Verification - Testing And Verification - ResultsResults

The song played repeatedly, indicating that The song played repeatedly, indicating that the forked process with priority zero was the forked process with priority zero was not starved out by the higher priority not starved out by the higher priority processes. All processes were shown to processes. All processes were shown to have been scheduled.have been scheduled.

Page 26: BrickOS Scheduling Solving The Low-Priority Starvation Problem

Thank You And Good Night Thank You And Good Night