====== SCHEDULING II ====== //Presented by:// Mubbasir Kapadia, Riyaz Haque and Albert Wang. ===== Document Articulation ===== - Review - Shortest Job First Scheduling - Proof of Optimality - Preemptive Round Robin Scheduling - Priority Scheduling - Multilevel Priority Queue Scheduling - Multilevel Feedback Queue Scheduling - Real Time Scheduling ===== Review ===== * //Long Term Scheduling// - It determines the programs that are admitted to the system for processing. It determines the degree of multiprogramming. * //Medium Term Scheduling// - It coordinates the number of processes that are partially or fully in main memory. * //Short Term Scheduling// - It determines which available process will be executed by the processor. It is known as the //dispatcher//. - **Non-Preemptive Scheduling** - Once the process is in running state, it continues to execute until it terminates or it blocks itself to wait for I/O or to request some OS Service. - **Preemptive Scheduling** - The currently running process may be interrupted and moved to the ready state by the OS. The decision to preempt may be performed when a new process arrives, when an interrupt occurs, or periodically based on clock interrupt. === Scheduling Criteria === * //Turn around time//: Interval of time between submission of process and its completion. * //Waiting Time//: Sum of periods spent waiting in the ready queue. * //Response Time//: It is the time from submission of request until the response is first received. * //CPU Utilization//: The degree of utilization of processor. * //Throughput//: Number of processes completed per unit time. * //Fairness//: Processes should be treated equally and system should be void of starvation. * //Priority enforcement//: Scheduling policy favors higher priority processes. ===== Shortest Job First Scheduling - Proof of Optimality ===== **Theorem:** Shortest Job First Scheduling has the lowest average waiting time of any possible //non-preemptive// schedule. **Proof by contraction:** Assume that there is a minimum schedule that is not Shortest Job First and has a lower average waiting time than Shortest Job First. Consider a set of jobs: Ji … Jn **Minimum Schedule Gantt Chart:** {{notes:minsched2.png|}} **Shortest Job First Schedule:** {{notes:sjf.png|}} We know that the service time for J5 is less than the service time for J3. i.e. **τJ5 < τJ3** **Contradiction Schedule:** {{notes:sjf.png|}} We observe, {{notes:contradiction.png|}} that the contradiction schedule has a lower average waiting time than the minimum schedule. Hence, the minimum schedule which is not SJF does not have minimum waiting time. ∴ By contradiction, //Shortest Job First Scheduling has lowest average waiting time of all non-preemptive scheduling algorithms.// ---- ===== Preemptive Round Robin Scheduling ===== This is a form of scheduling where the running jobs are interrupted or preempted to give the other jobs a chance to get access to the processor. It is designed for time sharing systems. It is similar to //First Come First Serve (FCFS)// but preemption is added to switch between processes at regular units of time called a //quantum Q//. Consider the following example assuming Time Quantum Q = 2: {{notes:roundrobin_table.png|}} **Gantt Chart:** {{notes:rrganntchart.png|}} **Calculation of Waiting Time and Turn around Time:** {{notes:rrtable2.png|}} {{notes:rrformula.png|}} Context Switching in Round Robin Scheduling - If you increase time quantum Q, * Average Turnaround time will decrease * Average waiting time will increase - First Come First Serve Scheduling is nothing but Round Robin Scheduling with infinite quantum Q. - Context Switching does impose the overhead over a context switch ϰ for every time a new process is scheduled. - Operating systems in use nowadays employ a variant of Round Robin Scheduling. === Comparison between Shortest Job First Scheduling and Round Robin Scheduling === We observe, Average Waiting Time for SJF > Average Waiting Time for Round Robin Scheduling Average Turnaround Time for SJF < Average Turnaround Time for Round Robin Scheduling Thus, a trade off is established between Round Robin Scheduling and Shortest Job Scheduling. Round Robin Scheduling results in lower average wait time but increases the average turnaround time. The reason being that processes in the waiting queue don't have to wait for running processes to complete but instead have to just wait for a multiple of Q units. === Starvation in Round Robin Scheduling === Consider the following list of processes that are subject to Round Robin Scheduling: {{notes:rrstarvation.png|}} **Gantt chart:** {{notes:rrstarvegannt.png|}} As we can see from the above figure, process A which has to still do 1 unit of work ends up waiting for the continuous stream of incoming processes and is subject to starvation. === A Solution: === Put all new jobs at the end of the list. This will eliminate starvation. **Gantt Chart:** {{notes:rrgannt2.png|}} Wait time reduced Reduce effect of context switch Increase Q: wait goes up, TT goes down Finite Jobs – unrealistic/non practical, only like web servers OS Schedule processes – unknown run time Ex. Mp3 player vs. CS111 hw software OS needs to know which processes are important ===== Priority Scheduling ===== In the case of Priority based scheduling, more CPU time is allotted to //important// jobs. Here, importance is measured by a per job parameter known as **Priority**. A small priority parameter implies high importance. **Note:** SJF Algorithm is a special case of general priority scheduling where the process with the smallest service time is given highest importance. === Strict Priority Scheduling === This is a variant of Round Robin Scheduling that obeys priority. Processes having lowest priority parameter are serviced first. Round Robin scheduling is employed among processes that have equal priority. Consider the following example: {{notes:prioritytable.png|}} **Gantt Chart:** {{notes:prioritygannt.png|}} === Priority Definition === Priorities can be defined either externally or internally. - Internal Priorities: The priority of a process is defined using some measurable internal factors like time limits, memory requirements, number of open files etc. - External Priorities: They are set by some criteria that is external to the OS. === Variations of Priority based Scheduling === - Preemptive Priority based Scheduling: A newly arrived process's priority is compared with an already existing priority. If it is of greater importance, then the current process is preempted else it continues. - Non Preemptive Priority Based Scheduling: The newly arrived process is put at the head of the priority queue. === The problem - Starvation === A process that is ready to run but waiting for the CPU is considered to be blocked. A priority scheduling algorithm can make some low priority processes wait indefinitely for the CPU. In a heavily loaded system, continuous stream of heavily loaded processes can prevent a low priority process from ever getting access to the CPU. This is known as starvation. === A solution - Aging === Aging is a technique of gradually raising the process priority parameter the longer that they run. This would ensure that high priority processes would not starve low priority processes of CPU time. ===== Multilevel Priority Queue Scheduling ===== This algorithm partitions the ready queue into several separate queues. The processes are permanently assigned to one queue based on some property of the process. Each queue has its own specific scheduling algorithm. Consider the following illustration of Multilevel priority queue scheduling: {{notes:mlq.png|}} Each queue has absolute priority over lower priority queues. No process in batch queue will be able to run until the queues above it are empty. Another possibility is to time slice between the queues by allotting each process with a certain portion of CPU time. ===== Multilevel Feedback Queue Scheduling ===== Here, processes are not permanently assigned to a queue on entry to the system. Instead, they are allowed to move between queues. The idea is to separate processes with different CPU burst characteristics. If a process uses too much CPU time, it will be moved to a lower priority queue. Similarly, a process that waits too long in a low priority queue will be moved to a higher priority queue. This form of aging prevents starvation. {{notes:mlfeedback.png|}} ===== Real Time Scheduling ===== Real time tasks can be classified as: - Hard Real Time Task: It is one that must meet its deadline. - Soft Real Time Task: It is one that has an associated deadline which is desirable but not mandatory. === Characteristics of Real Time OS === * Determinism - OS performs operations at fixed, predetermined time intervals * Responsiveness - It is concerned with how long after the acknowledgment, it takes an OS to service the interrupt. * User Control - In real time, user has fine grained control over priority. The user should be able to distinguish between hard and soft real time processes and to specify relative priorities within each class. * Reliability - The real time system should be reliable without any loss or degradation of performance. * Fail Soft Operation - It is a characteristic that refers to the ability to fail in such a manner as to preserve as much capability and data as possible. === Earliest Deadline First (Real Time) Scheduling === The earliest deadline first real time scheduling algorithm simply schedules the job with the earliest deadline. If any schedule exists for a given set of real time processes, then the earliest deadline schedule for that set of processes also exists. Consider the following example: {{notes:realtime.png|}} **Gantt Chart:** {{notes:realgannt.png|}} === Best Effort Scheduling === Unlike the case of real time scheduling where the process must meet its deadline or not be executed at all, best effort scheduling employs a strategy to try and meet the deadline of all the processes. However these processes generally have //soft deadlines//. Hence if a process is unable to meet its deadline, it is still executed. ====== SYNCHRONIZATION ====== ===== Document Articulation ===== - What is Synchronization? - Race Condition - An Illustration - Bank Deposits and Withdrawals ===== What is Synchronization? ===== Cooperating processes are those that can be affected by other processes executing in a system. Cooperating processes can either directly share a logical address space or be allowed to share data only through files or messages. The former is achieved using the concept of threads, discussed earlier. Concurrent access to shared data may result in data inconsistency. This chapter will discuss various mechanisms to ensure the orderly execution of cooperating processes that share a logical address space so that data consistency is maintained. This forms the basis of synchronization. //Synchronization is the coordination of individual actions in a sufficient and efficient manner.// It is done to ensure that data consistency is maintained (sufficient condition). In addition, utilization and performance must not be compromised to a great extent. Synchronization deals with three of our five goals for an operating system: * Utilization * Performance * Robustness ===== Race Condition ===== When several processes access and manipulate the same date concurrently and the outcome of the execution depends on the particular order in which the access takes place, it is referred to as a //race condition.// To guard against the race condition, we need to ensure that only one process at a time can be manipulating this shared data. To make this guarantee, we need the processes to be synchronized in some way. ===== An Illustration - Bank Deposits & Withdrawals ===== === Overview === Let's jump right in and look at an example about making deposits and withdrawals from a bank account. Suppose Professor Eddie's mother is looking out for his financial well-being and sets him up with a bank account. Both she and Eddie can make deposits and withdrawals from that account. The only issue is that Eddie lives on the West Coast while mom lives on the East Coast, so they may make transactions for this account at the same time. Here's the actual code we'll work with: == void deposit == void deposit (uint32_t amt){ eddie += amt; // D1 } The "eddie" variable stores how much is in the account. Assuming people are not making around forty-three billion dollar deposits, the deposit function works fine. == void withdraw == void withdraw (uint32_t amt){ eddie -= amt; } However, this withdraw function has an integer overflow error. If someone tries to withdraw more than what's in the account, the bank suddenly thinks they're billionaires. The following is an example: eddie = 10; withdraw(11); eddie = 42,949,672.95 == bool withdraw == The new withdraw function now has a boolean return value and correctly checks the balance to however much the user wants to withdraw. If there are enough funds, it subtracts the amount from the account and returns true. Otherwise, it returns false. bool withdraw (uint32_t amt){ if (eddie >= amt) { // W1 eddie -= amt; // W2 return true; // W3 }else // W4 return false; // W5 } === The Problem === The synchronization problem deals with two events that may conflict when happening at the same time. Due to the order in which code is run, unexpected results may occur. == Case 1 == Initial conditions / function calls: eddie = 5 M: withdraw(5) E: withdraw(5) There are two threads on the bank's machine that allows both functions to run at the same time. To that effect, the expected possible outcomes are as follows: - M gets 5, E returns false, and eddie = 0 - M returns false, E gets 5, and eddie = 0 The previous functions' executable code lines are labeled (please look above for familiarization). Here's a possible way in which we can get an unexpected outcome: Instruction Balance M W1 5 E W1 5 E W2 0 E W3 (return true) M W2 42949672.91 M W3 (return true) There is an error because the units of code that the computer runs is less than the length of a function. == Assembly code += and -= == In assembly, the += and -= lines of code in C need to be expanded into more lines of instructions. This is because those operations can only be done to local variables, and eddie is not a local variable. eddie += amt; // D1 expands to the following temp = eddie; // D1A temp += amt; // D1B eddie = temp; // D1C eddie -= amt; // W2 expands to the following temp = eddie; // W2A temp -= amt; // W2B eddie = temp; // W2C We will use these expanded lines of code for the following case. == Case 2 == Initial conditions / function calls: eddie = 5 M: deposit(5) E: withdaw(5) The new balance should be 5. However, the following is a possible run scenario to get 10: Instruction eddie temp E W1 5 - M D1A 5 -> 5 E W2A 5 -> 5 E W2B 5 0 E W2C 0 <- 0 E W3 (return true) M D1B 0 10 M D1C 10 <- 10 ===== Conclusion ===== As we've seen, improving synchronization is necessary to maintain robustness while increasing performance and utilization with multi-threading. The above example gave you a brief overview on the problems faced while dealing with synchronization. We will discuss this in great detail in the coming lectures.