You are on page 1of 104

RTOS Fundamentals

Intro to real time theory


In Real Time Systems, providing the result within a deadline is as important as providing the correct answer. Here A late answer is a wrong answer. This can be compared to a quiz program. A late answer is not accepted. A hard real time system is one in which missing a deadline can cause a great loss to life and property. Aerospace/ space navigation systems and nuclear power plants are examples. A soft real time system is one where the system is resilient to missing a few deadlines. Examples are DVD players and music systems. The user usually tolerates an occasional glitch.
2

Fast & hard real times


These two definitions do not include a notion of the speed with which the system must respond to. They describe the criticality of meeting the deadlines. If the system has to meet the deadline in a few micro or milli seconds, then the system is called as fast real time system. For example, watching a video on a broadband network. The system is receiving data at a few mbps. This is a fast real time system. But this is not a hard deadline system because a rare miss in audio/ video is tolerated and does not make our loss of life or property. Similarly hard realtime systems need not be fast.
3

Realtime systems
This timeliness factor which distinguishes realtime software from normal application software targeted at desktop computers. In realtime software, we have to ascertain that all deadlines are met before deploying the software. In desktop software, usually ensuring correctness is sufficient. Thus while developing realtime software, we should do Performance Analysis during the design phase.
5

Brief history of RTOS


In the olden days of computing, developers created software applications that included lowlevel machine code to initialize and interact with the systems hardware directly. The tight integration between the software and hardware resulted in non-portable applications. A small change in hardware resulted in rewriting the much of the application itself. These systems were difficult and costly to maintain.
6

History of RTOS
The so called operating system offers abstraction of the underlying hardware from the application code. In addition, the evolution of OS helped shift the design of software applications from large, monolithic applications to more modular, interconnected applications that could run on top of the operating system environment.
7

History of RTOS
In 60s and 70s, when mid-sized and mainframe computing was in its prime, UNIX was developed to facilitate multi-user access to expensive, limitedavailability computing systems. UNIX allowed to share these large and costly computers. Multi-user access was very efficient. UNIX was also ported to all types of machines from microcomputer to supercomputers. In 80s Windows operating system, targeted for personal computing environment through Graphical User Interface helped residential and business users interact with the PCs.
8

RTOS
An RTOS is not usually such a complex piece of software when compared to the mammoth size OSes currently available. Though current RTOSes provide a huge variety of features, a basic RTOS is just small enough to provide some scheduling, memory management and a decent level of hardware abstraction.
9

Similarities between a Real Time Operating System and General Purpose Operating System

Some level of multitasking, Software and hardware resource management Providing OS services to applications Abstracting the hardware from the software applications.

10

OS vs RTOS
A desktop OS is usually huge in size. It is not uncommon to see the OS using 300-500 MB just for their installation. But, in embedded systems, even 8-16MB of memory is considered to be luxury. A desktop OS has huge libraries for UI management, support for networking protocols and fancy features like Plug n Play. They also implement complex policies for network communication and facilities for binary reusability such as DLLs, COM/DCOM, .NET, etc.

11

Special requirements of an RTOS are:


Better reliability in embedded environment (harsh) Ability to scale up or down to meet the application needs (toy to aircraft) Faster performance Reduced memory needs Scheduling policies tailored for real-time embedded systems Support for diskless embedded systems Better portability to different hardware platforms
12

Kernel
In some applications, an RTOS consists only a kernel, which is the core supervisory software that provides minimal logic, scheduling and resource management algorithms. Every RTOS has a kernel. An RTOS can be a combination of various modules, including the kernel, a file system, networking protocol stacks and other components needed for a particular application.
13

Some of the common elements of the heart of an RTOS the kernel are:
Scheduler A set of algorithms that determines which task executes when. Objects Useful for developers to create applications for real-time embedded systems. Common kernel objects are tasks, semaphores and message queues. Services Operations that the kernel performs on an object. Eg timing, interrupt handling and resource management.
14

Every RTOS will provide at least the following features:


Task Creation / Management Scheduling Inter task Communication / Synchronization Memory Management Timers Support for ISRs Some good RTOSes provide support for TCP/IP, telenet, FTP, etc.
15

Desktop vs RTOS
In a desktop development environment, a programmer opens his IDE and types his code. Then he builds it using his compiler and then executes his program. Here OS is running already and it loads the executable program. The program makes uses of the OS services. The OS takes care of scheduling it. When the program completes, it exits. The OS can run other programs even while our program is running. Programs have a definite exit point and programs that contain infinite loop are considered bad.
16

BSP
But this is not the case in most of the embedded systems. Usually there will be no dedicated OS already running on the target to load our programs. In an embedded system the software written bus us, the RTOS (usually in the form of some library) and a special component called the Board Support Package (BSP) is bundled into a single executable file. This executable is burnt into a Boot-ROM or Flash. Sometimes, the code is obtained over a network on being powered up. Usually embedded systems cannot afford the luxury of having hard disks. Thus there is no OS during the startup. Here BSP is part of OS code in the sense that it is used by the OS to talk to different hardware in the board. In fact ,we write the software that is going to run on the target board.
17

Need for Board Support Package in Embedded Systems


The OS needs to interact with the hardware on the board. For example, if we have a TCP/IP stack integrated with our software, it should finally talk to the Ethernet Controller on our board to finally put the data in the networking medium. The TCP/IP package has no clue about the Ethernet controller (say, 3Com, Intel) and the location of the Ethernet controller and the ways to program it. Thus BSP is highly specific to both the board and the RTOS for which it is written. The BSP/ startup code will be the first to be executed at the start of the system.
18

BSP code does the following:


Initialization of processor (BSP code initializes the mode of operation of the processor, it sets various parameters required by the processor), Memory initialization, Clock setup and Setting up of various components such as cache. This is first part. These are low level stuff and are done in assembly language. The next part consists of drivers required by the RTOS to use some peripherals (eg Ethernet driver, video, URART, etc.). Coding BSP is a tough task in embedded systems as it requires mastery of both the hardware and software.
19

Various components of an RTOS Task Management


Simple software applications are typically designed to run sequentially, one instruction at a time, in a pre-determined chain of instructions. However, this scheme is inappropriate for realtime embedded applications, which generally handle multiple inputs and outputs within tight time constraints. Real-time embedded software applications must be designed for concurrency.
20

Concurrency
Concurrency design requires developers to decompose an application into small, schedulable, and sequential program units. When done correctly, concurrent design allows system multitasking to meet the performance and timing requirements for real-time system.
21

Task
It consists of the following: Task Creation, Task Scheduling and Task Deletion. A Task is the atomic unit of execution that can be scheduled by an RTOS to use the system resources. Thus a task is an independent thread of execution that can compete with other concurrent tasks for processor execution time. When we say that a task is an atomic unit, any other entity smaller than a task cannot compete for system resources. The resources such as CPU, memory, input / output devices, etc are called system resources.
22

Task Creation
A task first need to be created. A task is characterized by the parameters and supporting data structures: 1) A task name 2) Priority 3) Stack Size and 4) OS specific options. These parameters can be used to create a task. A typical call might look like as follows: result = task_create(TxTask, 100, 0x4000, OS_PREEMPTABLE); if result = = OS_SUCCESS) { // task created} At this stage, the code is in an embryonic state (Dormant). It still does not have the code to execute. But by now, a task control block (TCB) would have been created by the RTOS.
23

System tasks
When a kernel first starts, it creates its own set of system tasks and allocates the appropriate priority for each from a set of reserved priority levels. An application should avoid using these priority levels for its tasks because running application tasks at such level may affect the overall system performance or behavior. The system priorities are not be modified. Eg. initialization or startup task, idle task, logging task, exception-handling task and debug agent task (allows debugging with a host debugger).

24

Control Blocks
The use of control blocks is not limited to a task. There are control blocks for memory, synchronization, etc. The control blocks are internal to RTOS. There is absolutely no need for a programmer to access these blocks. But, a programmer need to know how these control blocks are used by the RTOS.

25

TCB
An RTOS usually reserves a portion of available memory for itself during startup. This chunk of memory is used to maintain structures such as TCB. The TCB will usually consists of the state of the task. ie the value of registers when the task was preempted earlier, its priority and its RTOS specific parameters (say scheduling policy). When a task is blocked, the value of the registers is saved in its context in TCB. When a task is scheduled again, the system registers are restored with these saved values, so that the task will know even if it was pre-empted. An RTOS uses the TCB of a task to store all the relevant information regarding the task. 26

Task states
A task can be in one of the following states: 1) Dormant 2) Ready 3) Running and 4) Blocked. Dormant When the task is created, but not added to RTOS for scheduling. Ready When a task is added to the RTOS for scheduling, it usually arrives in the ready state. But it cannot do so currently if a higher priority task is being executed. Running The task is currently using the CPU. When a task is running and if another higher priority task becomes ready, the task that is running is pre-empted and the highest priority task is scheduled for execution. Blocked During course of execution of a task, it may require a resource or input. In this case, if the resource / input is not immediately available, the task gets blocked.
27

Granular states
Some commercial kernel such as the VxWorks kernel, define other, granular states such as suspended, pended and delayed. Pended and delayed are sub-states of blocked state. A pended task is waiting for a resource that it needs to be freed. A delayed task is waiting for a timing delay to end. The suspended state exists for debugging purposes.
28

Different Task States

29

Ready State
When a task is first created and made ready to run, the kernel puts it into the ready state. Here the task actively competes with all other ready task for the processors execution time. The tasks in this state cannot move directly to the blocked state. But it can move to the running state. Because many tasks might be in the ready state, the kernals scheduler uses the priority of each task to determine which task to move to the running state.
30

Ready state
Many kernals support more than one task per priority level, allowing many more tasks in an application. Then the scheduling algorithm is quite complicated and involves maintaining a taskready list. Some kernals maintain a separate task-ready list for each priority level; others have one combined list. A kernel uses this list to move tasks from the ready state to the running state.
31

Running State
In a single-processor system, only one task can run at a time. When a task is moved to the running state, the processor loads its registers with this tasks context. The processor can then execute the tasks instructions and manipulate the associated stack. When a pre-empted task is put in the appropriate, priority-based location in the task-ready list, and the higher priority task is moved from the ready state to the running state. This state can move to the blocked state .

32

Blocked state
The possibility of blocked states is very important in real-time systems because without blocked states, lower priority tasks could not run. If higher priority tasks are not designed to block, CPU starvation can result. CPU starvation occurs when a higher priority task use all the CPU execution time and lower priority tasks do not get to run. When a task becomes unblocked, the task might move from the blocked state to the ready state if it is not the highest priority task. The task is then put into the task-ready list at the appropriate priority based location. However, if the unblocked state is the highest priority task, the task moves directly into the running state (without going to ready state) and preempts the currently running task. The preempted task is moved to the ready state and put into the appropriate priority-based location in the task-ready list. 33

Idle task
What happens if no task is ready to run and all of them are blocked? The RTOS will be in trouble. So, an RTOS will usually execute a task called idle task. An idle task does nothing. void IdleTask (void) { while(1); } This has no system calls. It has no code except an infinite loop. In RTOS, the idle task has the lowest priority. Many RTOS reserve a few lowest and highest priority tasks for themselves. For example, if an RTOS can provide 256 tasks, it may reserve the lowest 10 and the highest 10, leaving the user with 236 tasks of priorities in the range (10-246).

34

CPU loading
Though an idle task does nothing, we can use it to determine the CPU loading the average utilization ratio of the CPU. This can be done by making the idle task writing the system clock in some memory location whenever it gets scheduled. Is an ISR also a task? No. A task is a standalone executable entity. An ISR is a routine that is called by system in response to an interrupt event. But some new RTOSes model ISR as high priority threads.
35

Tasks, process and threads


The term task refers to something that needs to be done. In addition, we will have an order of priority and schedule timeline for executing these tasks. In the OS parlance, a task is defined as the program in execution and the related information maintained by the OS for the program. Task is also known as Job in the OS context. A program or part of it in execution is also called a Process. The terms Task, Job and Process refer to the same entity in the Os context and most often they are used interchangeably.
36

Process
A Process is a program or part of it, in execution. Multiple instances of the same program can execute simultaneously. A process needs various system resources like CPU for executing the process, memory for storing the code corresponding to the process and associated variables, I/O devices for information exchange, etc. A process is sequential in execution.
37

Structure of a process
The concept of Process leads to concurrent execution of tasks and the efficient utilization of the CPU and other system resources. A process mimics a processor in properties and holds a set of registers, process status, a Program Counter (PC) to point to the next executable instruction of the process, a stack for holding the local variables associated with the process and the code corresponding to the process.
38

39

Virtual Processor
A process which inherits all the properties of the CPU can be considered as a virtual processor, awaiting its turn to have its properties switched into the physical processor. When the process gets its turn, its registers and the program counter register becomes mapped to the physical registers of the CPU. The memory occupied by the process is segmented into 3 regions, namely, Stack memory, Data Memory and Code memory.
40

Virtual processor
The stack memory holds all temporary data such as variables local to the process. Data memory holds all the global data for the process. The code memory contains the program code corresponding to the process. On loading a process into the main memory, a specific area of memory is allocated for the process.
41

Memory organization of a process

42

Process Management
Process management deals with the creation of a process, setting up the memory space for the process, loading the processs code into the memory space, allocating system resources, setting up a Process Control Block for the process and process termination / deletion.

43

Threads
A thread is the primitive that can execute code. A thread is a single sequential flow of control within a process. Thread is also known as light weight process. A process can have many threads of execution. Different threads, which are part of a process, share the same address space; Meaning they share the data memory, code memory and heap memory area. Threads maintain their own thread status (CPU register values), Program Counter (PC) and stack.
44

Memory organization of a process and its thread

45

Multithreading
A process / task in embedded application may be a complex or lengthy one and it may contain various sub operations like getting input form I/O devices connected to the processor, performing some internal calculations / operations, updating some I/O devices etc. If all the sub functions of a task are executed in sequence, the CPU utilization may not be efficient. For example, if the process is waiting for a user input, the CPU enters the wait state for the event, and the process execution also enters a wait state.

46

Multithreading
Instead of this single sequential execution of the whole process, if the task / process is split into different threads carrying out the different sub functionalities of the process, the CPU can be effectively utilized and when the thread corresponding to the I/O operation enters the wait state, another thread which do not require the I/O event for their operation can be switched into execution. This leads to speedy execution of the process and the efficient utilization of the processor time and resources. The multithreaded architecture of a process can be visualized with the thread-process diagram as shown below.
47

48

Advantages of Multithreading
If the process is split into multiple threads, which executes a portion of the process, there will be a main thread and rest of the threads will be created within the main thread. The advantages of multithreading are: Better memory utilization. Multiple threads of the same process share the address space for data memory. This also reduces the complexity of inter thread communication since variables can be shared across the threads. Since the process is split into different threads, when one thread enters a wait state, the CPU can be utilized by other threads of the process that do not require the event, while the other thread is waiting, for processing. This speeds up the execution of the process. Efficient CPU utilization. The CPU is engaged all time.

49

50

Multiprocessing and multitasking


Multiprocessing describes the ability to execute multiple processes simultaneously. Multiprocessor systems possess multiple CPUs and can execute multiple processes simultaneously. The ability of an OS to have multiple programs in memory, which are ready for execution, is called as multiprogramming. In a uniprocessor system, it is possible to achieve some degree of pseudo parallelism in the execution of multiple processes by switching the execution among different processes. The ability of an OS to hold multiple processes in memory and switch the processor (CPU) from one process to another process is known as multitasking.
51

Context switching
In a multitasking environment, when task / process switching happens, the virtual processor gets its properties converted into that of the physical processor. The switching of the virtual processor to physical processor is controlled by the scheduler of the OS kernel. During CPU switching, current context of execution are saved and used later when the CPU executes the process again. This is known as context switching. The act of saving the context is called as Context Saving. The process of retrieving the saved context is called as Context Retrieval.
52

Toss Juggling
The skilful object manipulation game is a real world example for multitasking illusion. The juggler uses a number of objects (balls, rings, etc) and throws them up and catches them. At any point of time, he throws only one ball and catches only one per hand. However, the speed at which he is switching the balls for throwing and catching creates the illusion, he is throwing and catching multiple balls to spectators.
53

Co-operative Multitasking
There are various types of multitasking existing in the operating systems context. Co-operative Multitasking It is the most primitive form of multitasking in which a task/process gets a chance to execute only when the currently executing task / process voluntarily relinquishes the CPU. Here any task / process can hold the CPU as much time as it wants. It involves the mercy of the tasks for getting the CPU time for execution, it is known as co-operative multitasking. If the currently executing task is non-cooperative, the other tasks may have to wait for a long time to get the CPU.
54

Preemptive multitasking
It ensures that every task / process gets a chance to execute. When and how much time a process gets is dependent on the implementation of the preemptive scheduling. Here the currently running task/ process is preempted to give a chance to other tasks / processes to execute. The preemption of task may be based on time slots or task / process priority.
55

Non-preemptive multitasking
Here, the process / task which is currently given the CPU time, is allowed to execute until it terminates or enters the Blocked / Wait state, waiting for an I/O system resource. The co-operative and non-preemptive multitasking differs in their behavior when they are in the Blocked / Wait state. In the co-operative multitasking, the currently executing task / process need not relinquish the CPU when it enters the Blocked / Wait state, waiting for an I/O, or a shared resource access or an event to occur whereas in non-preemptive mutli tasking the currently executing task relinquishes the CPU when it waits for an I/O or system resource or an event to occur.
56

Scheduler
There should be some mechanism in place to share the CPU among the different tasks and to decide which process / task is to be executed at a given point of time. Determining which task / process is to be executed at a given point of time is known as task / process scheduling. The scheduling polices are implemented in an algorithm and it is run by the kernel as a service. The kernel service / application which implements the scheduling algorithm, is known as Scheduler.
57

Selection of Scheduling algorithm


This depends on the following factors: CPU utilization The scheduling algorithm should always make the CPU utilization high. It is a direct measure of how much percentage of the CPU is being utilized. Throughput It gives an indication of the number of processes executed per unit of time. It should always be higher. Response time It is the time elapsed between the submission of a process and the first response. It should be as least as possible.
58

Selection of Scheduling algorithm


Turnaround time It is the amount of time taken by a process for completing its execution. It includes the time spent by the process for waiting for the main memory, time spent in the ready queue, time spent on completing the I/O operations, and the time spent in execution. It should be minimal for a good scheduling algorithm. Waiting time It is the amount of time spent by a process in the Ready queue waiting to get the CPU time for execution. It should be minimal for a good scheduling algorithm.

59

Queues for scheduling


The various queues maintained by OS along with CPU scheduling are: Job Queue: It contains all the processes in the system. Ready Queue: It contains all the processes, which are ready for execution and waiting for CPU to get their turn for execution. It is empty when there is no process ready for running. Deviec Queue: It contains the set of processes, which are waiting for an I/O device.
60

Task scheduling pre-emptive scheduling


Task scheduling is one of the important reason for choosing an RTOS. The programmer can assign priorities to various tasks and rest assured that the RTOS would do the needed scheduling. There are many scheduling policies. The most used ones are: Strictly pre-emptive scheduling It is one of the most widely used scheduling policies in an RTOS. But this is not the preferred one in a desktop. Here at any time, only the highest priority task that is ready to run executes. If a task Ti runs, it means that all tasks Tj with priorities lesser than Ti are blocked. This scheduling policy ensures that important tasks are handled first and the less important ones later. For example, in an aircraft cruise control system, the flight controller task will have more priority then a task 61 that controls the air-conditioning system.

Pros and cons of pre-emptive scheduling


Pros: Once the priorities are set properly, we can rest assured that only the important things are handled first. Cons: It is possible that one or more of the lower priority tasks do not get to execute at all. Hence to avoid this proper analysis should be done at design phase. Note that in almost all systems, ISRs will have highest priority irrespective of the priorities assigned to the task.
62

Time slicing
Here the CPU time is shared between all the tasks. Each task gets a fraction of CPU time. There is no notion of priority here. This scheduling is also known as round robin scheduling. It is not used in its original form. It can be used in conjunction with pre-emptive scheduling. In a pre-emptive system, if two or more tasks have same priority, we can make the scheduler use time slicing for those tasks with the same priority. Pros: No need of complex analysis of the system. This kind of kernel is easy to implement. The pre-emption time of a task is deterministic ie if a task is pre-empted, we will know exactly the time after which the task will be scheduled (if the number of tasks in the system do not vary in time). Cons: This is a very rigid scheduling policy ie there is no 63 notion of priority.

Fairness Scheduling
Here every task is given an opportunity to execute. Unlike pre-emptive scheduling, in which a lower priority task may not get an opportunity to execute, here every task will be given a fair chance to execute. Though some kind of priority mechanism could be incorporated here, it is not strict. Priority of a task, which has not executed for some period will gradually be increased by the RTOS and will finally get a chance to execute.
64

Pros and cons of fairness scheduling


This scheduling policy is complex. How to vary priority of tasks so that fairness is achieved is itself a tough task? And it does not fit right in real time systems. This kind of scheduling is widely used in desktop OS. We listen to music while compiling our programs. Pros: Every task will get an opportunity to execute. Cons: Introduces non determinism into the system.

65

Non-preemptive Scheduling
Here the currently executing task / process is allowed to run until it terminates or enters the wait state waiting for an I/O or system resource. The various types of nonpreemptive scheduling algorithms are: First-Come-First Server (FCFS) / FIFO scheduling Here the algorithm allocated CPU time to the processes based on the order in which they enter the Ready queue. The first entered process is serviced first. It is same as any real world application where queue systems are used. Eg Ticketing reservation system where people need to stand in a queue and the first person standing in the queue is serviced first. FCFS is also known as First In First Out (FIFO).
66

Drawback of FCFS
The major drawback here is that it favors monopoly of process. A process, which does not contain any I/O operation, continues it execution until it finishes its task. If the process contains any I/O operation, the CPU is relinquished by the process. In general, FCFS favors CPU bound processes and I/O bound processes may have to wait until the completion of the CPU bound process, if the currently executing process is a CPU bound process. This leads to poor device utilization. The average waiting time is not minimal for FCFS scheduling algorithm.
67

LCFS / LIFO
The Last Come First Served scheduling algorithm also allocates CPU time to the processes based on the order in which they are entered in the Ready state queue. The last entered process is serviced first. LCFS scheduling is also known as LIFO where the process, which is put last into the Ready queue is serviced first. It is also not optimal and possesses the same drawback as that of FCFS algorithm.
68

Shortest Job First


The algorithm sorts the Ready queue each time a process relinquishes the CPU (either the process terminates or enters the Wait state for I/O system or system resource) to pick the process with shortest (least) estimated completion / run time. If SJF, the process with the shortest estimated runtime is scheduled first, followed by the next shortest process, and so on.
69

Drawback of SJF
The average waiting time for a given set of process is minimal in SJF scheduling and so it is optimal compared to other non-preemptive scheduling like FCFS. The main drawback of SJF algorithm is that a process whose estimated execution completion time is high may not get a chance to execute if more and more processes with least estimated execution time enters Ready queue before the process with longest estimated execution time started its execution (in pre-emptive SJF). This condition is known as Starvation. Another drawback of SJF is that it is difficult to know in advance the next shortest process in the Ready queue for scheduling since new processes with different estimated execution time keep entering the Ready queue at any point of time.
70

Priority Based Scheduling


The Turn Around Time (TAT) and waiting time for processes in non-preemptive scheduling varies with the type of scheduling algorithm. Priority based non-preemptive scheduling algorithm ensures that a process with high priority is serviced at the earliest compared to other low priority processes in the Ready queue. The priority of a task / process can be indicated by many mechanisms. In the SJF algorithm, each task is prioritized in the order of the time required to complete the task. The lower the time required for completing a process the higher is its priority.
71

Priority in Windows CE
Another way of priority assigning is associating a priority to the task / process at the time of creation of the task / process. Windows CE supports 256 levels or priority, while creating a task. Here 0 indicates highest priority and 255 indicates the lowest priority. The non-preemptive priority based scheduler sorts the Ready state queue based on priority and picks the process with the highest level of priority for execution.
72

Aging
Similar to SJF scheduling algorithm, non-preemptive priority based algorithm also possess the drawback of Starvation where a process whose priority is low may not get a chance to execute if more and more processes with higher priorities enter the Ready queue before the process with lower priority started its execution. Starvation can be tackled in priority based nonpreemptive scheduling by dynamically raising the priority of the low priority task which is under starvation. This technique is known as Aging.

73

Preemptive Scheduling
In preemptive scheduling, every task in the Ready state gets a chance to execute. When and how often each process gets a chance to execute (gets the CPU time) is dependent on the type of preemptive scheduling algorithm used for scheduling the processes. Here the scheduler can pre-empt (stop temporarily) the currently executing task and select another task from the Ready queue for execution. When to pre-empt a task and which task is to be picked up from the Ready queue for execution after preempting the current task is purely dependent on the scheduling algorithm. A task which is preempted by the scheduler is moved to the Ready queue. The act of moving a Running process into the Ready queue by the scheduler, without the processes requesting for it is known as Preemption. Two important approaches used in preemptive scheduling are 74 time-based and priority based preemption.

Preemptive SJF scheduling / Shortest Remaining Time (SRT)


The non-preemptive SJF scheduling algorithm sorts the Ready queue only after completing the execution of the current process or when the process enters Wait state, whereas the preemptive SJF scheduling algorithm sorts the Ready queue when a new process enters the Ready queue and checks whether the execution time of the new process is shorter than the remaining of the total estimated time for the currently executing process.
75

Preemptive SJF scheduling / Shortest Remaining Time (SRT)


If the execution time of the new process is less, the currently executing process is preempted and the new process is scheduled for execution. Thus preemptive SJF scheduling always compares the execution completion time of a new process entered the Ready queue with the remaining time for completion of the currently executing process and schedules process with the shortest remaining time for execution. Preemptive SJF is also known as Shortest Remaining Time (SRT) scheduling.
76

Round Robin Scheduling


The term Round Robin is very popular among the sports and games activities. In the round robin league each team in the group gets an equal chance to play against the rest of the teams in the same group whereas in the Knock out league the losing team in a match moves out of the tournament. In round robin scheduling, each process in the Ready queue is executed for a pre-defined time slot. The execution starts with picking up the first process in the Ready queue. It is executed for a pre-defined time and when the pre-defined time elapses or the process completes (before the pre-defined time slice), the next process in the Ready queue is selected for execution. This is repeated for all the processes in the Ready queue.
77

RR drawbacks
Once each process in the Ready queue is executed for the pre-defined time period, the scheduler comes back and picks the first process in the Ready queue again for execution. The sequence is repeated. Round Robin scheduling is similar to FCFS scheduling and the only difference is that a time slice based preemption is added to switch the execution between the processes in the Ready queue. The Ready queue can be considered as a circular queue in which the scheduler picks up the first process for execution and moves to the next till the end of the queue and then comes back to the beginning of the queue to pick up the first process.
78

More on Round Robin Scheduling


The time slice of a kernel varies in order of a few microseconds to milliseconds. Certain OS kernels allow the time slice as user configurable. Round robin scheduling ensures that each process gets a fixed amount of CPU time for execution. If a process terminates before the elapse of the time slice, the process releases the CPU voluntarily and the next process in the queue is scheduled for execution by the scheduler.
79

Priority based scheduling


Priority based preemptive scheduling algorithm is same as that of the non-preemptive priority based scheduling except for the switching of execution between tasks. In preemptive scheduling, any high priority process entering the Ready queue is immediately scheduled for execution whereas in the non-preemptive scheduling any high priority process entering the Ready queue is scheduled only after the currently executing process completes its execution or only when it voluntarily relinquishes the CPU.
80

Priority based scheduling


Priority based preemptive scheduling gives Real-Time attention to high priority tasks. Thus priority based preemptive scheduling is adopted in systems which demands Real Time behavior. Most of the RTOSs make use of the preemptive priority based scheduling algorithm for process scheduling. Preemptive priority based scheduling also suffers from Starvation. This can also be eliminated by Aging technique.

81

Task Synchronization
So far we talked about many tasks executing in the RTOS. In all but trivial systems, these tasks need to interact with each other. ie they must synchronize and communicate with each other. Let us explain this with a real-time example. When the tasks are independent ie there is no communication between the tasks, they do not share any resources between them. This can be compared with two roads that run parallel to each other and hence do not meet.
82

Task synchronization
Vehicles can ply on these roads safely without colliding with ones in the parallel road. But the case becomes difficult when we have two intersecting roads. Here we need an explicit mechanism like a traffic signal to make sure that the vehicles ply without getting into any mishaps. This situation is different, because, there is a shared region between the roads. So the traffic on the two roads need explicit synchronization. The traffic signal is needed only at the region of intersection. There is no need for this synchronization either before or after this region. 83

Task synchronization methods


There are two ways of achieving synchronization with the tasks: Task synchronization using mutexes. Task synchronization using semaphores. Task synchronization using mutexes Problems occur only when a resource is shared among tasks and synchronization needs to be done only during resource acquisition and release. For example, consider two tasks that want to share a printer. Let task A want to print the numbers: 1 2 3. And let task B want to print the alphabets: A B C. If these tasks are scheduled in a round robin (time slicing) method, then the printout will be: 1 2 A B 3 C ( or any other junk).
84

Mutex
The solution to this problem is that one of the tasks can acquire the printer resource, use it and then release it. To implement this solution, we need to use a mutex short name for Mutual Exclusion. It is a mechanism to exclude other tasks to use a resource when a specific task has acquired it. For example, task A can be coded as: // Task A code // . Mutex_acquire (printer_mutex); print (1); print (2); print (3) ; mutex_release (printer_mutex) ; 85

More on mutex
Similarly, task B can be coded as : // Task B code // Mutex_acquire (printer_mutex); print (A); print (B) ; print (C) ; mutex_release (printer_mutex) ; At any point of time if both the tasks want to use the printer, they first try to acquire the mutex. Since, we are considering only a single processor model, the task, which makes the first attempt will acquire it.
86

Example for mutex


Let us consider a case where task A has acquired the printer_mutex. // Task A code // mutex_acquire (printer_mutex); print (1); - Pre-empted here print (2); Let us now consider the task B has a higher priority and it gets scheduled after print (1). And now, let task B also want to print something. It will now try to acquire the printer_mutex. But it cannot, since task A has already acquired the mutex. 87

Mutex
// Task B code // mutex_acquire (printer_mutex); --- Blocked here print (A); print (B); The task B will be blocked now. Ie we say B is blocked on resource. Since task B is blocked, task A gets to resume again and completes its printing. It then releases the mutex. Now, task B can resume and continue with its printing. We should remember that if task B is a higher priority task, the execution would shift to task B immediately after task A releases the mutex.
88

More on mutex
Consider the following code of task A: // print (3); mutex_release (printer_mutex); my_foo( ); //some other function called from task A In a truly pre-emptive system, the execution will be transferred to task B immediately after execution of mutex_release. Statement my_foo will be executed only after task A is scheduled again.
89

Psuedo code for mutex


# include <my_os.h> // The printer mutex is a global variable so that both the tasks can access it mutex printer_mutex; int main( ) { // ... task_create (TaskA ) ; task_create (TaskB ) ; // } void TaskA (Parms) { } void TaskB (Params) { }
90

Race conditions
Mutexes are also required when two tasks share data using global variables. Let us consider a case where two tasks are writing into contiguous memory locations and another task uses these values produced by the tasks. In concurrent programming language, the first two tasks that generate the values are called producers and the one that uses these values is called the consumer. A task can be a producer and a consumer at the same time.
91

Race conditions
Let us use a pointer ptr to write into the list. To write, we can use *prt = 8; Assume that ptr points to memory location 0x4000. ptr is a global variable and both the tasks P1 and P2 can access it. Consider the following situation: P1 reads the value of ptr. After P1 reads the value of ptr from the memory, it gets pre-empted by P2 that writes say ptr = 12; Now, the contents of memory location 0x4000 will be changed to 12.
92

Race conditions
Before P2 increments the pointer, task P1 is scheduled again. Now the contents of P2 are lost when P1 writes 8 into same memory location. This condition where data consistency is lost because of lack of synchronization of the component tasks of a system is called a race condition. This belongs to one of the worst categories of bugs nonrepeatable bugs. To avoid this problem, shared global variables must be used only with synchronization.

93

Priority inversion
It is one of the issues that must be addressed during the analysis and design of realtime systems. In a pre-emptive system, at any point of time, only the task with the highest priority executes. But due to some reasons, if a higher priority task is blocked because of some lower priority task, then a Priority Inversion is said to have occurred. It can happen in two ways: Bounded priority inversion and Unbounded priority inversion.
94

Bounded priority inversion


Let us consider a system with two tasks A (TA) and B (TB). Let priority of TA be higher than that of TB. Let initially TA be executing and after sometime, TA gets blocked and TB scheduled. Now, let TB acquire a mutex corresponding to a resource shared between TA and TB. After sometime, before TB gets to finish its critical section code, TA gets scheduled (since TAs priority is higher). After sometime, TA tries to acquire the mutex for the resource shared between TA and TB. But, it cannot acquire the mutex because, it has already been acquired by TB. Because of this TA is blocked. Now, TB runs till it completes its critical section code and releases the mutex. Once the mutex is released, TA begins execution.
95

Bounded priority inversion


Here we see that TA gets blocked for a period, because of lower priority than task TB in acquiring a shared resource. So, in this case priority inversion is said to have occurred. How long is TA blocked? The answer is, in worst case, TA will be blocked for the period equal to the critical section of TB (ie if TB is preempted immediately after acquiring the mutex).
96

More on bounded priority inversion


// Task B code mutex_acquire (my_mutex); TB is pre-empted here // critical section code mutex_release (my_mutex); Here the period for which the priority inversion occurs is bounded. The worst case is that the priority inversion occurs for the period equal to complete TB critical section. So this is called bounded priority inversion.
97

Unbounded priority inversion


This is dangerous than bounded priority inversion method. It is a case when the time for which priority inversion is unbounded ie we cannot fix how long the priority inversion will occur. Here higher priority task will not be able to provide its services for a unknown period of time. This could cause failure of the entire system. Let us consider a system with 3 tasks Ta, Tb, Tc in decreasing order of priority (Ta has the highest priority). Initially assume that the highest priority task Ta is running and gets blocked. Assume Tb is also blocked due to some reason. Now Tc starts running. The task Tc acquires the mutex for the resource shared 98 between Ta and Tc and enters the critical region.

Unbounded priority inversion


Now it gets preempted by Tb, which gets pre-empted again by task Ta. After sometime, Ta tries to acquire the mutex for the shared resource. But, Tc had already taken the mutex. Once Ta gets blocked, Tb starts running. Now, Tc is still blocked and cannot release the mutex required. Unlike the previous case, we cannot say how long it will be before the lower priority task releases the resource needed by higher priority task. We will have to wait for the intermediate priority task(s) to complete before the lower priority task will release the resource. 99 So this is called as unbounded priority inversion.

Preventing priority inversion


There are 2 schemes to avoid priority inversion. They are: 1) Priority Inheritance Protocol (PIP) 2) Priority Ceiling Protocol (PCP). Priority Inheritance Protocol (PIP) Here the priority of a task using a shared resource shall be made equal to the priority of the highest priority task that is blocked for the resource at the current instant. This is done so that the priority of a lower priority task is boosted in such a way that the priority inversion gets bounded. This method needs the support of an OS.
100

Example
Consider an RTOS where 1 is the highest priority. Let 10 tasks, with priorities 1-10 execute in the system. Let us consider that the tasks with priority 2 and 7 share a resource R. Let T7 (lower priority) acquire the shared resource R and get pre-empted by task T5 before releasing it. Later, let T2 get scheduled and get blocked for the resource R. Immediately priority of T7 is boosted to 2. Now, T7 with boosted priority will be able to complete its critical section and release the mutex. Once the mutex is released, its previous priority is restored so that the actual high priority task can continue its execution and enter its critical section.
101

Priority Ceiling Protocol


Here we assign a priority with the resource during design time. During runtime, any task, which wants to use the resource will acquire the priority associated with the resource. The priority associated with the resource is the priority of the highest priority task associated with the resource. Example Let us assume that the system has three tasks and two resources that are shared. Let us assume that 1 is the highest priority in the system. Let tasks T1, T2, T3 have priorities 1, 2 and 3. Then we can form a table mapping resources to tasks. Resource Sharing Tasks Priority R1 T1, T2, T3 1 102 R2 T2, T3 2

Priority ceiling protocol


Any task that wants to use R1, then it has to do the following: Say, if T3 wants to use R1, it sets its priority to 1 and then access the resource. Now, task T1 cannot pre-empt T3 because its priority has increased to 1. After using the resource, the task restores its own priority. It does not need any support from OS. There is no mutex / semaphore is required. We use the priority changing mechanism provided by the RTOS.
103

Disadvantages of Priority ceiling protocol


This method is manual ie the priority is associated with the resource manually. So for large systems, maintaining priorities associated with resources can be error prone. Manual set/reset of priorities: In it original form (without mutexes), after using the resource, if tasks do not reset their priority it could cause havoc. Time slicing not allowed: While using PCP, we have to adopt only a strict pre-emptive scheduling policy. PCP will fail if we mix pre-emptive and time-slicing.

104

You might also like