Os Notes Sits Complete
Os Notes Sits Complete
UNIT-I
The idea of multiprogramming is to assign CPUs to other processes while the current process might not be
finished. This has the below advantages.
1) The user gets the feeling that he/she can run multiple applications on a single CPU even if the CPU is
running one process at a time.
2) CPU is utilized better
All modern operating systems like MS Windows, Linux, etc are multiprogramming operating systems.
2
Page
5. PARALLEL SYSTEMS
A parallel system in an operating system is a computer system that uses multiple processors to perform
tasks simultaneously.
The goal of a parallel system is to improve performance and throughtput
A parallel processing system can carry out simultaneous data-processing to achieve faster execution time.
For instance, while an instruction is being processed in the ALU component of the CPU, the next instruction
can be read from memory.
The primary purpose of parallel processing is to enhance the computer processing capability and increase
its throughput, i.e. the amount of processing that can be accomplished during a given interval of time.
The above diagram shows one possible way of separating the execution unit into eight functional units
6
operating in parallel.
Page
The adder and integer multiplier performs the arithmetic operation with integer numbers.
The floating-point operations are separated into three circuits operating in parallel.
The logic, shift, and increment operations can be performed concurrently on different data. All
units are independent of each other, so one number can be shifted while another number is being
incremented.
Examples
Solaris
OSF/1
Micros
DYNIX
Locus
Mach
Maintainability/Extensibility.
Page
Modularity.
1. Kernel: This is the core part of the operating system, managing the system's resources and
communication between hardware and software components. The kernel performs tasks such as process
management, memory management, task scheduling, and file management.
2. Process Management: The OS manages processes through scheduling, which involves deciding which
processes run when there are multiple processes. It handles process creation, termination, and the
switching between processes.
3. Memory Management: This component is responsible for managing the computer's memory, allocating
space for applications, ensuring that they do not interfere with each other, and managing virtual memory if
the system uses it.
4. File System Management: The OS manages files on a computer, handling tasks related to file creation,
deletion, and organization. It also manages directories and maintains the file system's integrity.
5. Device Management: Through device drivers, the OS manages device communication via their
respective drivers. It performs the tasks of device allocation and de-allocation, and also handles device
errors.
6. Security and Access Control: The OS ensures that all access to system resources is secure. It manages
user permissions and ensures that unauthorized users cannot access the system.
7. User Interface: This component allows interaction with the user, which can be through a command-line
9
8. Networking: The OS manages the sharing of resources and information across networked computers. It
handles network connections and manages data transmission and reception.
9. System Utilities: These are additional tools and utilities that help manage, maintain, and control the
computer system. Examples include disk defragmenters, system monitors, and antivirus programs.
Each of these components plays a vital role in the overall functionality and efficiency of the operating
system, ensuring that the computer system operates smoothly and securely
I/O operation means read or write operation with any file or any specific I/O device.
Operating system provides the access to the required I/O device when required.
3. File system manipulation: A file represents a collection of related information.
Computers can store files on the disk (secondary storage), for long-term storage purpose. Examples of
storage media include magnetic tape, magnetic disk and optical disk drives like CD, DVD. Each of these
10
media has its own properties like speed, capacity, data transfer rate and data access methods.
Page
The OS monitors and records how various resources are being used. This includes:
CPU time: How much processing time each user or process consumes.
Memory usage: How much RAM each process allocates.
Disk usage: How much storage space each user or process occupies.
Network usage: How much data is transmitted and received.
8. Protection and Security: Considering a computer system having multiple users and concurrent
execution of multiple processes, the various processes must be protected from each other's activities.
Protection refers to a mechanism or a way to control the access of programs, processes, or users to the
resources defined by a computer system. Following are the major activities of an operating system with
respect to protection −
SYSTEM CALLS
System calls provide an interface to the services made available by an operating system. These calls are
generally available as routines written in C and C++, although certain low-level tasks (for example, tasks
where hardware must be accessed directly) may have to be written using assembly-language instructions.
An example to illustrate how system calls are used: writing a simple program to read data from one file and
copy them to another file.
Frequently, systems execute thousands of system calls per second. Most programmers never see this level
of detail, however. Typically, application developers design programs according to an application
programming interface (API). The API specifies a set of functions that are available to an application
programmer, including the parameters that are passed to each function and the return values the
programmer can expect.
Three of the most common APIs available to application programmers are the Windows API for Windows
systems, the POSIX API for POSIX-based systems (which include virtually all versions of UNIX, Linux, and
Mac OSX), and the Java API for programs that run on the Java virtual machine. A programmer accesses an
API via a library of code provided by the operating system. In the case of UNIX and Linux for programs
written in the C language, the library is called libc.
Behind the scenes, the functions that make up an API typically invoke the actual system calls on behalf of
the application programmer. For example, the Windows function CreateProcess() (which unsurprisingly is
used to create a new process) actually invokes the NTCreateProcess() system call in the Windows kernel.
12
Page
For most programming languages, the run-time support system (a set of functions built into libraries
included with a compiler) provides a system call interface that serves as the link to system calls made
available by the operating system. The system-call interface intercepts function calls in the API and invokes
the necessary system calls within the operating system.
13
Page
Process control
File management
Device management
Information maintenance
Communications
Protection
Process control
A running process needs to halt its execution either normally or abnormally.
If a system call is made to terminate the running program, a dump of memory is sometimes taken and an
error message generated which can be diagnosed by a debugger
end, abort
load, execute
create process, terminate process
get process attributes, set process attributes
wait for time
wait event, signal event
allocate and free memory
File management
OS provides an API to make these system calls for managing files
THE PROCESS:
A process is an active program i.e. a program that is under execution. It is more than the program code as it
includes the program counter, process stack, registers, program code etc. Compared to this, the program
code is only the text section.
A program is not a process by itself as the program is a passive entity, such as file contents, while the
process is an active entity containing program counter, resources etc.
PROCESS STATE:
A process changes its state as it executes. This state partially depends on the current activity of a process.
The different states that a process is in during its execution are explained using the following diagram.
PROCESS STATE TRANSISTIONS:
CONTEXT SWITCHING:
The Context switching is a technique or method used by the operating system to switch a process from one
state to another to execute its function using CPUs in the system. When switching perform in the system, it
stores the old running process's status in the form of registers and assigns the CPU to a new process to
execute its tasks. While a new process is running in the system, the previous process must wait in a ready
queue. The execution of the old process starts at that point where another process stopped it. It defines the
characteristics of a multitasking operating system in which multiple processes shared the same CPU to
perform multiple tasks without the need for additional processors in the system.
17
Page
COOPERATING PROCESSES
There are various processes in a computer system, which can be either independent or cooperating
processes that operate in the operating system. It is considered independent when any other processes
operating on the system may not impact a process. Process-independent processes don't share any data
18
with other processes. On the other way, a collaborating process may be affected by any other process
executing on the system. A cooperating process shares data with another.
Page
Here, you see a diagram that shows cooperation by sharing. In this diagram, Process P1 and P2 may
cooperate by using shared data like files, databases, variables, memory, etc.
2. Cooperation by Communication
The cooperating processes may cooperate by using messages. If every process waits for a message from
another process to execute a task, it may cause a deadlock. If a process does not receive any messages, it
may cause starvation.
19
Page
Here, you have seen a diagram that shows cooperation by communication. In this diagram, Process P1 and
P2 may cooperate by using messages to communicate.
THREADS
Definition:
A thread refers to a single sequential flow of activities being executed in a process; it is also known as the
thread of execution or the thread of control.
A thread is a basic unit of CPU utilization; it comprises a thread ID, a program counter, a register set, and a
stack. It shares with other threads belonging to the same process its code section, data section, and other
operating-system resources, such as open files and signals. A traditional (or heavyweight) process has a
single thread of control. If a process has multiple threads of control, it can perform more than one task at a
time.
20
Page
Process is heavy weight or resource Thread is light weight, taking lesser resources
1
intensive. than a process.
Process switching needs interaction with Thread switching does not need to interact
2
operating system. with operating system.
Multiple processes without using threads Multiple threaded processes use fewer
5
use more resources. resources.
In multiple processes each process One thread can read, write or change another
6
operates independently of the others. thread's data.
BENEFITS OF THREADS:
The benefits of multithreaded programming can be broken down into four major categories:
1. Responsiveness. Multithreading an interactive application may allow a program to continue
running even if part of it is blocked or is performing a lengthy operation, thereby increasing
responsiveness to the user.
2. Resource sharing. Processes can only share resources through techniques such as shared memory
and message passing.
3. Economy. Allocating memory and resources for process creation is costly. Because threads share
the resources of the process to which they belong, it is more economical to create and context
switch threads.
4. Scalability. The benefits of multithreading can be even greater in a multiprocessor architecture,
where threads may be running in parallel on different processing cores.
21
Page
In this case, the thread management kernel is not aware of the existence of threads. The thread library
contains code for creating and destroying threads, for passing message and data between threads, for
scheduling thread execution and for saving and restoring thread contexts. The application starts with a
single thread.
Advantages
Disadvantages
In this case, thread management is done by the Kernel. There is no thread management code in the
application area. Kernel threads are supported directly by the operating system. Any application can be
programmed to be multithreaded. All of the threads within an application are supported within a single
process.
The Kernel maintains context information for the process as a whole and for individuals threads within the
process. Scheduling by the Kernel is done on a thread basis. The Kernel performs thread creation,
22
scheduling and management in Kernel space. Kernel threads are generally slower to create and manage
Page
Kernel can simultaneously schedule multiple threads from the same process on multiple processes.
If one thread in a process is blocked, the Kernel can schedule another thread of the same process.
Kernel routines themselves can be multithreaded.
Disadvantages
Kernel threads are generally slower to create and manage than the user threads.
Transfer of control from one thread to another within the same process requires a mode switch to
the Kernel.
CONCEPT OF MULTHREADS:
The term multithreading refers to an operating system's capacity to support execution among fellow threads
within a single process. The advantages of implementation of threads are resource ownership (Address
space and utilized file I/O) and execution (TCB and scheduling). All threads inside a process will have to
share compute resources such as code, data, files, and memory space with its peer thread, but stacks and
registers will not be shared, and each new thread will have its own stacks and registers.
It is important to note that requests from one thread do not block requests from other separate
threads, which improves application responsiveness.
The term 'multithreading' also reduces the number of computing resources used and makes them
more efficient.
The concept of multithreading is the event of a system executing many threads, with the execution
of these threads being of two types:
Concurrent and Parallel multithread executions.
The concurrent process of threads is defined as the ability of a processor to move execution
resources between threads in a multithreaded process on a single processor.
When each thread in a multithreaded program executes on a separate processor at the same time, it
is referred to as parallel execution.
The threads of the same process share the following items during multithreading:
Address space
Global variables
Accounting information
Opened files, used memory and I/O
Child processes
Pending alarms
Signal and signal handlers
The following things are private (not shared) to the individual thread of a process in multithreading.
1. Stack (parameters, temporary, variables return address, etc)
2. TCB (Thread Control Block): It contains 'thread ids', 'CPU state information' (user-visible, control
and status registers, stack pointers), and 'scheduling information' (state of thread priority, etc.)
Advantages of Multithreading
Improves execution speed (by combining CPU machine and I/O wait times).
Multithreading can be used to achieve concurrency.
Reduces the amount of time it takes for context switching.
Improves responsiveness.
23
Increases throughput.
Disadvantages of Multithreading
Because the threads share the same address space and may access resources such as open files,
difficulties might arise in managing threads if they utilize incompatible data structures.
If we don't optimize the number of threads, instead of gaining performance, we may lose
performance.
If a parent process requires several threads to function properly, the child processes should be
multithreaded as well, as they may all be required.
Multithreading Models
Some operating system provide a combined user level thread and Kernel level thread facility. Solaris is a
good example of this combined approach. In a combined system, multiple threads within the same
application can run in parallel on multiple processors and a blocking system call need not block the entire
process. Multithreading models are three types
The many-to-many model multiplexes any number of user threads onto an equal or smaller number of
kernel threads.
The following diagram shows the many-to-many threading model where 6 user level threads are
multiplexing with 6 kernel level threads. In this model, developers can create as many user threads as
necessary and the corresponding Kernel threads can run in parallel on a multiprocessor machine. This
model provides the best accuracy on concurrency and when a thread performs a blocking system call, the
kernel can schedule another thread for execution.
Many-to-one model maps many user level threads to one Kernel-level thread. Thread management is done
24
in user space by the thread library. When thread makes a blocking system call, the entire process will be
blocked. Only one thread can access the Kernel at a time, so multiple threads are unable to run in parallel
Page
on multiprocessors.
There is one-to-one relationship of user-level thread to the kernel-level thread. This model provides more
concurrency than the many-to-one model. It also allows another thread to run when a thread makes a
blocking system call. It supports multiple threads to execute in parallel on microprocessors.
Disadvantage of this model is that creating user thread requires the corresponding Kernel thread. OS/2,
windows NT and windows 2000 use one to one relationship model.
25
Page
User-level threads are faster to create and Kernel-level threads are slower to create
1
manage. and manage.
User-level thread is generic and can run on Kernel-level thread is specific to the
3
any operating system. operating system.
26
Page
The process scheduling is the activity of the process manager that handles the removal of the running
process from the CPU and the selection of another process on the basis of a particular strategy.
Process scheduling is an essential part of a Multiprogramming operating systems. Such operating systems
allow more than one process to be loaded into the executable memory at a time and the loaded process
shares the CPU using time multiplexing.
Categories of Scheduling:
1. Non-preemptive: Here the resource can’t be taken from a process until the process completes
execution. The switching of resources occurs when the running process terminates and moves to a
waiting state.
2. Preemptive: Here the OS allocates the resources to a process for a fixed amount of time. During
resource allocation, the process switches from running state to ready state or from waiting state to
ready state. This switching occurs as the CPU may give priority to other processes and replace the
process with higher priority with the running process.
SCHEDULING QUEUES:
All processes, upon entering into the system, are stored in the Job Queue.
Processes in the Ready state are placed in the Ready Queue.
Processes waiting for a device to become available are placed in Device Queues. There are unique
device queues available for each I/O device.
A new process is initially put in the Ready queue. It waits in the ready queue until it is selected for
execution (or dispatched). Once the process is assigned to the CPU and is executing, one of the following
several events can occur:
The process could issue an I/O request, and then be placed in the I/O queue.
The process could create a new subprocess and wait for its termination.
The process could be removed forcibly from the CPU, as a result of an interrupt, and be put back in
the ready queue.
27
Page
SCHEDULERS:
Schedulers are special system software which handle process scheduling in various ways. Their main task
is to select the jobs to be submitted into the system and to decide which process to run. Schedulers are of
three types −
Long-Term Scheduler
Short-Term Scheduler
Medium-Term Scheduler
It is also called a job scheduler. A long-term scheduler determines which programs are admitted to the
system for processing. It selects processes from the queue and loads them into memory for execution.
Process loads into the memory for CPU scheduling.
The primary objective of the job scheduler is to provide a balanced mix of jobs, such as I/O bound and
processor bound. It also controls the degree of multiprogramming. If the degree of multiprogramming is
stable, then the average rate of process creation must be equal to the average departure rate of processes
leaving the system.
On some systems, the long-term scheduler may not be available or minimal. Time-sharing operating
systems have no long term scheduler. When a process changes the state from new to ready, then there is
use of long-term scheduler.
It is also called as CPU scheduler. Its main objective is to increase system performance in accordance with
the chosen set of criteria. It is the change of ready state to running state of the process. CPU scheduler
selects a process among the processes that are ready to execute and allocates CPU to one of them.
Short-term schedulers, also known as dispatchers, make the decision of which process to execute next.
Short-term schedulers are faster than long-term schedulers.
A running process may become suspended if it makes an I/O request. A suspended processes cannot make
any progress towards completion. In this condition, to remove the process from memory and make space
for other processes, the suspended process is moved to the secondary storage. This process is
called swapping, and the process is said to be swapped out or rolled out. Swapping may be necessary to
improve the process mix.
Short-Term Medium-Term
S.N. Long-Term Scheduler
Scheduler Scheduler
It is a process swapping
1 It is a job scheduler It is a CPU scheduler
scheduler.
It provides lesser
It controls the degree of It reduces the degree of
3 control over degree of
multiprogramming multiprogramming.
multiprogramming
It is almost absent or
It is also minimal in It is a part of Time
4 minimal in time sharing
time sharing system sharing systems.
system
Scheduling Objectives
Preemptive Scheduling:
Preemptive scheduling is used when a process switches from running state to ready state or from
waiting state to ready state.
The resources (mainly CPU cycles) are allocated to the process for the limited amount of time and
then is taken away, and the process is again placed back in the ready queue if that process still has
CPU burst time remaining.
That process stays in ready queue till it gets next chance to execute.
30
Page
Non-Preemptive Scheduling:
Basis for
Preemptive Scheduling Non Preemptive Scheduling
Comparison
Once resources are allocated to a process, the
The resources are allocated to a
Basic process holds it till it completes its burst time
process for a limited time.
or switches to waiting state.
Process cannot be interrupted till it
Interrupt Process can be interrupted in between.
terminates or switches to waiting state.
If a high priority process frequently If a process with long burst time is running
Starvation arrives in the ready queue, low CPU, then another process with less CPU burst
priority process may starve. time may starve.
Preemptive scheduling has overheads Non-preemptive scheduling does not have
Overhead
of scheduling the processes. overheads.
Flexibility Preemptive scheduling is flexible. Non-preemptive scheduling is rigid.
Preemptive scheduling is cost Non-preemptive scheduling is not cost
Cost
associated. associative.
SCHEDULING CRITERIA
There are several different criteria to consider when trying to select the "best" scheduling
algorithm for a particular situation and environment, including:
o CPU utilization - Ideally the CPU would be busy 100% of the time, so as to waste 0 CPU
cycles. On a real system CPU usage should range from 40% (lightly loaded) to 90% (heavily
loaded.)
o Throughput - Number of processes completed per unit time. May range from 10 / second
to 1 / hour depending on the specific processes.
o Turnaround time - Time required for a particular process to complete, from submission
time to completion.
o Waiting time - How much time processes spend in the ready queue waiting their turn to
get on the CPU.
o Response time - The time taken in an interactive program from the issuance of a command
to the commence of a response to that command.
Arrival Time: Time at which the process arrives in the ready queue.
Completion Time: Time at which process completes its execution.
Burst Time (BT): Time required by a process for CPU execution.
Turn Around Time (TAT): Time Difference between completion time and arrival time.
Turn Around Time = Completion Time – Arrival Time
Waiting Time (WT): Time Difference between turnaround time and burst time.
Waiting Time = Turn Around Time – Burst Time
31
Page
SCHEDULING ALGORITHMS
The process which arrives first in the ready queue is firstly assigned the CPU.
In case of a tie, process with smaller process id is executed first.
It is always non-preemptive in nature.
Jobs are executed on first come, first serve basis.
It is a non-preemptive, pre-emptive scheduling algorithm.
Easy to understand and implement.
Its implementation is based on FIFO queue.
Poor in performance as average wait time is high.
Advantages-
It is simple and easy to understand.
It can be easily implemented using queue data structure.
It does not lead to starvation.
Disadvantages-
It does not consider the priority or burst time of the processes.
It suffers from convoy effect i.e. processes with higher burst time arrived before the processes with
smaller burst time.
Example 1:
32
Page
Example 2:
Consider the processes P1, P2, P3 given in the below table, arrives for execution in the same order,
with Arrival Time 0, and given Burst Time,
ARRIVAL
PROCESS BURST TIME
TIME
P1 0 24
P2 0 3
P3 0 3
Gantt chart
P1 P2 P3
0 24 27 30
P1 0 24
P2 24 27
27 30
33
P3
Page
Example 3:
Consider the processes P1, P2, P3, P4 given in the below table, arrives for execution in the
same order, with given Arrival Time and Burst Time.
PROCESS ARRIVAL TIME BURST TIME
P1 0 8
P2 1 4
P3 2 9
P4 3 5
Gantt chart
P1 P2 P3 P4
0 8 12 21 26
TURN AROUND
PROCESS WAIT TIME
TIME
P1 0 8–0=8
P2 8–1=7 12 – 1 = 11
P3 12 – 2 = 10 21 – 2 = 19
P4 21 – 3 = 18 26 – 3 = 23
Total Wait Time = 0 + 7 + 10 + 18 = 35 ms Average Waiting Time = (Total Wait Time) / (Total number of
processes)= 35/4 = 8.75 ms
Total Turn Around Time = 8 + 11 + 19 + 23 = 61 ms
Average Turn Around time = (Total Turn Around Time) / (Total number of processes) 61/4 = 15.25 ms
Throughput = 4 jobs/26 sec = 0.15385 jobs/sec
Advantages-
SRTF is optimal and guarantees the minimum average waiting time.
34
It provides a standard for other algorithms since no other algorithm performs better than it.
Page
Example-01:
Consider the set of 5 processes whose arrival time and burst time are given below
Solution:
If the CPU scheduling policy is SJF non-preemptive, calculate the average waiting time and average
turnaround time.
Gantt Chart
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Now,
Average Turn Around time = (4 + 15 + 5 + 6 + 10) / 5 = 40 / 5 = 8 unit
Average waiting time = (3 + 11 + 3 + 0 + 7) / 5 = 24 / 5 = 4.8 unit
Example-02:
Consider the set of 5 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time
35
P1 3 1
Page
Exit time /
Turn Around
Process Id Completion Waiting time
time
time
P1 4 4–3=1 1–1=0
P2 6 6–1=5 5–4=1
P3 8 8–4=4 4–2=2
P4 16 16 – 0 = 16 16 – 6 = 10
P5 11 11 – 2 = 9 9–3=6
Now,
Average Turn Around time = (1 + 5 + 4 + 16 + 9) / 5 = 35 / 5 = 7 unit
Average waiting time = (0 + 1 + 2 + 10 + 6) / 5 = 19 / 5 = 3.8 unit
Example-03:
Consider the set of 6 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time
P1 0 7
P2 1 5
P3 2 3
P4 3 1
P5 4 2
P6 5 1
If the CPU scheduling policy is shortest remaining time first, calculate the average waiting time and average
turnaround time.
Solution:
Gantt Chart
36
Page
Now, we know-
Example -04:
Consider the set of 3 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time
P1 0 9
P2 1 4
P3 2 9
If the CPU scheduling policy is SRTF, calculate the average waiting time and average turn around time.
Solution:
Gantt Chart
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Turn Around
Process Id Exit time Waiting time
time
P1 13 13 – 0 = 13 13 – 9 = 4
P2 5 5–1=4 4–4=0
P3 22 22- 2 = 20 20 – 9 = 11
Now,
Average Turn Around time = (13 + 4 + 20) / 3 = 37 / 3 = 12.33 unit
Average waiting time = (4 + 0 + 11) / 3 = 15 / 3 = 5 unit
Example-05:
37
Consider the set of 4 processes whose arrival time and burst time are given below
Page
P1 0 20
P2 15 25
P3 30 10
P4 45 15
If the CPU scheduling policy is SRTF, calculate the waiting time of process P2.
Solution
Gantt Chart
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Thus,
Turn Around Time of process P2 = 55 – 15 = 40 unit
Waiting time of process P2 = 40 – 25 = 15 unit
38
Page
Disadvantages-
It leads to starvation for processes with larger burst time as they have to repeat the cycle many
times.
Its performance heavily depends on time quantum.
Priorities cannot be set for the processes.
Thus, smaller value of time quantum is better in terms of response time. With increasing value of time
quantum,
Number of context switch decreases
Response time increases
Chances of starvation increases
Thus, higher value of time quantum is better in terms of number of context switch.
With increasing value of time quantum, Round Robin Scheduling tends to become FCFS Scheduling.
When time quantum tends to infinity, Round Robin Scheduling becomes FCFS Scheduling.
The performance of Round Robin scheduling heavily depends on the value of time quantum.
The value of time quantum should be such that it is neither too big nor too small.
Example-01:
Consider the set of 5 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time
P1 0 5
P2 1 3
P3 2 1
P4 3 2
P5 4 3
If the CPU scheduling policy is Round Robin with time quantum = 2 unit, calculate the average waiting time
and average turnaround time.
Solution:
Ready Queue- P5, P1, P2, P5, P4, P1, P3, P2, P1
Gantt Chart
39
Now, we know-
Turn Around time = Exit time – Arrival time
Page
Problem-02:
Consider the set of 6 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time
P1 0 4
P2 1 5
P3 2 2
P4 3 1
P5 4 6
P6 6 3
If the CPU scheduling policy is Round Robin with time quantum = 2, calculate the average waiting time
and average turnaround time.
Solution
Ready Queue- P5, P6, P2, P5, P6, P2, P5, P4, P1, P3, P2, P1
Gantt chart
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Turn Around
Process Id Exit time Waiting time
time
P1 8 8–0=8 8–4=4
P2 18 18 – 1 = 17 17 – 5 = 12
P3 6 6–2=4 4–2=2
P4 9 9–3=6 6–1=5
40
P5 21 21 – 4 = 17 17 – 6 = 11
19 – 6 = 13 13 – 3 = 10
Page
P6 19
Problem-03: Consider the set of 6 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time
P1 5 5
P2 4 6
P3 3 7
P4 1 9
P5 2 2
P6 6 3
If the CPU scheduling policy is Round Robin with time quantum = 3, calculate the average waiting time and
average turnaround time.
Solution
Ready Queue- P3, P1, P4, P2, P3, P6, P1, P4, P2, P3, P5, P4
Gantt chart
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Turn Around
Process Id Exit time Waiting time
time
P1 32 32 – 5 = 27 27 – 5 = 22
P2 27 27 – 4 = 23 23 – 6 = 17
P3 33 33 – 3 = 30 30 – 7 = 23
P4 30 30 – 1 = 29 29 – 9 = 20
P5 6 6–2=4 4–2=2
P6 21 21 – 6 = 15 15 – 3 = 12
Now,
Average Turn Around time = (27 + 23 + 30 + 29 + 4 + 15) / 6 = 128 / 6 = 21.33 unit
Average waiting time = (22 + 17 + 23 + 20 + 2 + 12) / 6 = 96 / 6 = 16 unit
Out of all the available processes, CPU is assigned to the process having the highest priority.
In case of a tie, it is broken by FCFS Scheduling.
Page
The waiting time for the process having the highest priority will always be zero in preemptive
mode.
The waiting time for the process having the highest priority may not be zero in nonpreemptive
mode.
Priority scheduling in preemptive and non-preemptive mode behaves exactly same under following
conditions-
The arrival time of all the processes is same
All the processes become available
Advantages-
It considers the priority of the processes and allows the important processes to run first.
Priority scheduling in pre-emptive mode is best suited for real time operating system.
Disadvantages-
Processes with lesser priority may starve for CPU.
There is no idea of response time and waiting time.
Problem-01:
Consider the set of 5 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time Priority
P1 0 4 2
P2 1 3 3
P3 2 1 4
P4 3 5 5
P5 4 2 5
If the CPU scheduling policy is priority non-preemptive, calculate the average waiting time and average
turnaround time. (Higher number represents higher priority)
Solution
Gantt Chart
Now, we know-
Turn Around time = Exit time – Arrival time
42
Problem-02:
Consider the set of 5 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time Priority
P1 0 4 2
P2 1 3 3
P3 2 1 4
P4 3 5 5
P5 4 2 5
If the CPU scheduling policy is priority preemptive, calculate the average waiting time and average turn
around time. (Higher number represents higher priority).
Solution
Gantt Chart
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Turn Around
Process Id Exit time Waiting time
time
P1 15 15 – 0 = 15 15 – 4 = 11
P2 12 12 – 1 = 11 11 – 3 = 8
P3 3 3–2=1 1–1=0
P4 8 8–3=5 5–5=0
P5 10 10 – 4 = 6 6–2=4
Now,
Average Turn Around time = (15 + 11 + 1 + 5 + 6) / 5 = 38 / 5 = 7.6 unit
Average waiting time = (11 + 8 + 0 + 0 + 4) / 5 = 23 / 5 = 4.6 unit
43
For example, CPU-bound jobs can be scheduled in one queue and all I/O-bound jobs in another queue. The
Process Scheduler then alternately selects jobs from each queue and assigns them to the CPU based on the
algorithm assigned to the queue.
The ready queue has been partitioned into seven different queues using the multilevel queue scheduling
technique. These processes are assigned to one queue based on their priority, such as memory size, process
priority, or type. The method for scheduling each queue is different. Some queues are utilized for the
foreground process, while others are used for the background process. The foreground queue may be
scheduled using a round-robin method, and the background queue can be scheduled using
an FCFS strategy.
A multilevel queue-scheduling algorithm with four queues to understand how this scheduling works:
1. System process: The OS has its process to execute, which is referred to as the System Process.
2. Interactive processes: It is a process in which the same type of interaction should occur.
3. Batch processes: Batch processing is an operating system feature that collects programs and data
into a batch before processing starts.
4. Student processes: The system process is always given the highest priority, whereas the student
processes are always given the lowest.
Every queue would have an absolute priority over the low-priority queues. No process may execute until the
high-priority queues are empty. In the above instance, no other process may execute until and unless the
queues for system, interactive, and editing processes are empty. If an interactive editing process enters the
ready queue while a batch process is underway, the batch process will be preempted.
Advantages
You can use multilevel queue scheduling to apply different scheduling methods to distinct
processes.
It will have low overhead in terms of scheduling.
44
Disadvantages
Page
Example Problem:
Let's take an example of a multilevel queue-scheduling (MQS) algorithm that shows how the multilevel queue
scheduling work. Consider the four processes listed in the table below under multilevel queue scheduling.
The queue number denotes the process's queue.
P1 0 4 1
P2 0 3 1
P3 0 8 2
P4 10 5 4
Queue 1 has a higher priority than queue 2. Round Robin is used in queue 1 (Time Quantum = 2), while
FCFS is used in queue 2.
Working:
1. Both queues have been processed at the start. Therefore, queue 1 (P1, P2) runs first (due to greater
priority) in a round-robin way and finishes after 7 units.
2. The process in queue 2 (Process P3) starts running (since there is no process in queue 1), but while
it is executing, P4 enters queue 1 and interrupts P3, and then P3 takes the CPU and finishes its
execution.
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Turn Around
Process Id Exit time Waiting time
time
P1 6 6–0=6 6–4=2
P2 7 7–0=7 7–3=4
P3 20 20 – 0 = 20 20 – 8 = 12
P4 15 15 – 5 = 5 5–5=0
Now,
Average Turn Around time = (6 + 7 + 20 + 5) / 4 = 38 / 4 = 9.5 unit
Average waiting time = (2 + 4 + 12 + 0) / 4 = 18 / 4 = 4.5 unit
45
This strategy prioritizes operations that require I/O and are interactive. It is a distinct process with a distinct
CPU burst time. It enables a process to switch between queues. If a process consumes too much processor
time, it will be switched to the lowest priority queue. A process waiting in a lower priority queue for too long
may be shifted to a higher priority queue. This type of aging prevents starvation.
The parameters of the multilevel feedback queue scheduler are as follows:
1. The scheduling algorithm for every queue in the system.
2. The queues number in the system.
3. The method for determining when a queue should be demoted to a lower-priority queue.
4. When a process is upgraded to a higher-priority queue, this process determines when it gets
upgraded.
5. The method for determining which processes will enter the queue and when those processes will
require service
Example:
Consider the set of 3 processes whose arrival time and burst time are given below
Process Id Arrival time Burst time
P1 0 36
P2 16 20
P3 20 12
Q1 P1 P2 P3
Q2 P1 P2 P3
Q3 P1
Gantt Chart:
P1 P1 P2 P3 P1 P2 P3 P1
0 8 16 24 32 48 60 64 68
Now, we know-
46
Now,
Average Turn Around time = (68 + 32 + 44) / 3 = 144 / 3 = 48 unit
Average waiting time = (32 + 12 + 24) / 4 = 68 / 3 = 22.67 unit
MULTIPLE PROCESSOR SCHEDULING:
To increase the system's overall performance, numerous processors or cores are frequently used in modern
computer systems. The operating system must be able to effectively schedule processes to execute on
various processors, though, in order to make the best use of these resources.
Multiple processor scheduling involves deciding which processes should be assigned to which processor or
core and how long they should be permitted to run. While ensuring that all processes are fairly and
appropriately prioritized, the objective is to achieve efficient utilization of the available processors.
The system's numerous CPUs communicate often and share a common bus, memory, and other peripherals.
As a result, the system is said to be strongly connected. These systems are employed whenever large amounts
of data need to be processed, and they are mostly used in satellite, weather forecasting, etc.
The ideal scheduling method for a system with a single processor cannot be determined by any rule or policy.
There is also no ideal scheduling strategy for a system with several CPUs.
Approaches to Multiple Processor Scheduling
47
Symmetric Multiprocessing
In an SMP system, each processor is comparable and has the same access to memory and I/O resources. The
CPUs are not connected in a master-slave fashion, and they all use the same memory and I/O subsystems.
This suggests that every memory location and I/O device are accessible to every processor without
restriction. An operating system manages the task distribution among the processors in an SMP system,
allowing every operation to be completed by any processor.
Processor Affinity:
Processor Affinity refers to a process with an affinity for the processor on which it is currently
running. When a process executes on a specific CPU, the cache memory is affected.
The processor's cache is populated by the process's most recently accessed data, so successive
memory accesses are commonly satisfied in the cache memory.
Assume the process is moved to a different CPU. In that situation, the contents of the first
processor's cache memory must be invalidated, and the second processor's cache must be
repopulated.
Most symmetric multiprocessing (SMP) systems try to avoid process migration by keeping the
same process running on the same processor due to the cause invalidating and repopulating caches
is expensive.
48
Page
1. Soft Affinity
2. Hard Affinity
Soft Affinity
The term "soft affinity" refers to an operating system's policy of keeping a process running on the same
processor, and it will not ensure that it will do so.
Hard Affinity
It enables a process to define a subset of processors on which it may execute. Some operating systems like
Linux implement soft affinity and offer system calls, such as sched setaffinity(), that support hard affinity
which allows a process to migrate between processors.
Load Balancing
In a multi-processor system, all processors may not have the same workload. Some may have a long
ready queue, while others may be sitting idle. To solve this problem, load balancing comes into the
picture.
Load Balancing is the phenomenon of distributing workload so that the processors have an even
workload in a symmetric multi-processor system.
In symmetric multiprocessing systems which have a global queue, load balancing is not required. In
such a system, a processor examines the global ready queue and selects a process as soon as it
becomes ideal.
However, in asymmetric multi-processor with private queues, some processors may end up idle
while others have a high workload.
Push Migration: In push migration, a task routinely checks the load on each processor. Some
processors may have long queues while some are idle. If the workload is unevenly distributed, it
will extract the load from the overloaded processor and assign the load to an idle or a less busy
processor.
Pull Migration: In pull migration, an idle processor will extract the load from an overloaded
processor itself.
Multi-Core Processors
A multi-core processor is a single computing component comprised of two or more CPUs called
cores. Each core has a register set to maintain its architectural state and thus appears to the
operating system as a separate physical processor.
A processor register can hold an instruction, address, etc.
Since each core has a register set, the system behaves as a multi-processor with each core as a
processor.
Symmetric multiprocessing systems which use multi-core processors allow higher performance at
low energy.
Memory Stall
When processor accesses memory then it spends a significant amount of time waiting for the data
to become available. This situation is called memory stall.
49
It occurs for various reasons such as cache miss, which is accessing the data that is not in the cache
memory.
Page
A System Call Interface (SCI) provides a way for user applications to interact with the operating system’s
kernel. For process management, system calls allow the creation, execution, synchronization, and
termination of processes.
An error in one program can adversely affect many processes, it might modify data of another program or
also can affect the operating system. For example, if a process stuck in the infinite loop then this infinite loop
could affect the correct operation of other processes. So to ensure the proper execution of the operating
system, there are two modes of operation:
User mode:
When the computer system is run by user applications like creating a text document or using any
application program, then the system is in user mode. When the user application requests for a service
from the operating system or an interrupt occurs or system call, then there will be a transition from user to
kernel mode to fulfil the requests.
Note: To switch from kernel mode to user mode, the mode bit should be 1.
Kernel Mode: When the system boots, the hardware starts in kernel mode and when the operating system
is loaded, it starts user application in user mode. To provide protection to the hardware, we have privileged
instructions which execute only in kernel mode. If the user attempts to run privileged instruction in user
mode then it will treat instruction as illegal and traps to OS. Some of the privileged instructions are:
1. Handling Interrupts
2. To switch from user mode to kernel mode.
3. Input-Output management.
Certain types of tasks do not require any type of hardware support, that’s why certain types of processes
are to be made hidden from the user. These tasks can be deal separately by using the Dual Mode of the
50
operating system.
Page
Basically, whenever the operating system works on the user applications, it held in the user mode. When
the user requests for some hardware services, a transition from User Mode to the Kernel Mode occurs
which is done by changing the mode bit from 1 to 0. Also the mode bit again changed to 1 for returning
back in the User Mode.
A new process known as a "child process" is created with the fork system call which runs concurrently with
the process called the parent process. fork system call in OS returns an integer value and requires no
arguments. After the creation of a new child process, both processes then execute the next command
following the fork system call. Therefore, we must separate the parent from the child by checking
the returned value of the fork():
Negative: A child process could not be successfully created if the fork() returns a negative value.
Zero: A new child process is successfully created if the fork() returns a zero.
Positive: The positive value is the process ID of a child's process to the parent. The process ID is
the type of pid_t that is defined in sys/types.h.
However, the parent and child processes are stored in different memory locations. These memory spaces
contain the same information, therefore any operations carried out by one process do not affect the other.
A child process uses the same open files, CPU registers, and the same pc(program counter) used in the
parent process.
The use of the fork() system call is to create a new process by duplicating the calling process. The fork()
system call is made by the parent process, and if it is successful, a child process is created.
The fork() system call does not accept any parameters. It simply creates a child process and returns the
process ID. If a fork() call is successful :
51
The OS will create two identical copies of the address space for parent and child processes.
Page
Therefore, the address spaces of the parent and child processes are different.
The exit system call is made by a process in its code or indirectly through library code.
The exit system call deletes all buffers and closes all open files.
The exit system call modifies data structures like the memory free list, open file table, and resource
table.
The operating system reclaims the memory used by the process.
The exit system call returns a status parameter value to the parent process
In operating systems, the "wait" system call is a function used by a parent process to suspend its own
execution until one of its child processes terminates, allowing the parent to retrieve the exit status of the
completed child process before continuing its own execution; essentially, it makes the parent process
"wait" for a child process to finish before proceeding further.
The waitpid system call is used to wait for child processes to terminate and obtain their exit status.
exec() System Call
The exec system call is an operating system function that replaces the current process with a new program.
It's also known as an overlay.
DEADLOCKS
System Model
For the purposes of deadlock discussion, a system can be modeled as a collection of limited
resources, which can be partitioned into different categories, to be allocated to a number of
processes, each having different needs.
Resource categories may include memory, printers, CPUs, open files, tape drives, CD-ROMS, etc.
By definition, all the resources within a category are equivalent, and a request of this category can
be equally satisfied by any one of the resources in that category. If this is not the case ( i.e. if there is
some difference between the resources within a category ), then that category needs to be further
divided into separate categories. For example, "printers" may need to be separated into "laser
printers" and "color inkjet printers".
Some categories may have a single resource.
In normal operation a process must request a resource before using it, and release it when it is
done, in the following sequence:
1. Request - If the request cannot be immediately granted, then the process must wait until
the resource(s) it needs become available. For example the system calls open( ), malloc( ),
53
DEADLOCK CHARACTERIZATION
NECESSARY CONDITIONS
Resource-Allocation Graph
In some cases deadlocks can be understood more clearly through the use of Resource-Allocation
Graphs, having the following properties:
o A set of resource categories, { R1, R2, R3, . . ., RN }, which appear as square nodes on the
graph. Dots inside the resource nodes indicate specific instances of the resource. ( E.g. two
dots might represent two laser printers. )
o A set of processes, { P1, P2, P3, . . ., PN }
o Request Edges - A set of directed arcs from Pi to Rj, indicating that process Pi has
requested Rj, and is currently waiting for that resource to become available.
o Assignment Edges - A set of directed arcs from Rj to Pi indicating that resource Rj has been
allocated to process Pi, and that Pi is currently holding resource Rj.
o Note that a request edge can be converted into an assignment edge by reversing the
direction of the arc when the request is granted. (However note also that request edges
point to the category box, whereas assignment edges emanate from a particular instance
dot within the box.)
o For example:
54
Page
If a resource-allocation graph contains no cycles, then the system is not deadlocked. ( When looking
for cycles, remember that these are directed graphs. ) See the example in Figure 7.2 above.
If a resource-allocation graph does contain cycles AND each resource category contains only a
single instance, then a deadlock exists.
If a resource category contains more than one instance, then the presence of a cycle in the resource-
allocation graph indicates the possibility of a deadlock, but does not guarantee one. Consider, for
example, Figures 7.3 and 7.4 below:
DEADLOCK PREVENTION
Deadlocks can be prevented by preventing at least one of the four required conditions:
1. Mutual Exclusion
Unfortunately some resources, such as printers and tape drives, require exclusive access by a single
process.
Page
To prevent this condition processes must be prevented from holding one or more resources while
simultaneously waiting for one or more others. There are several possibilities for this:
o Require that all processes request all resources at one time. This can be wasteful of system
resources if a process needs one resource early in its execution and doesn't need some
other resource until much later.
o Require that processes holding resources must release them before requesting new
resources, and then re-acquire the released resources along with the new ones in a single
new request. This can be a problem if a process has partially completed an operation using
a resource and then fails to get it re-allocated after releasing it.
o Either of the methods described above can lead to starvation if a process requires one or
more popular resources.
3. No Preemption
Preemption of process resource allocations can prevent this condition of deadlocks, when it is
possible.
o One approach is that if a process is forced to wait when requesting a new resource, then all
other resources previously held by this process are implicitly released, ( preempted ),
forcing this process to re-acquire the old resources along with the new resources in a single
request, similar to the previous discussion.
o Another approach is that when a resource is requested and not available, then the system
looks to see what other processes currently have those resources and are themselves
blocked waiting for some other resource. If such a process is found, then some of their
resources may get preempted and added to the list of resources for which the process is
waiting.
o Either of these approaches may be applicable for resources whose states are easily saved
and restored, such as registers and memory, but are generally not applicable to other
devices such as printers and tape drives.
4. Circular Wait
One way to avoid circular wait is to number all resources, and to require that processes request
resources only in strictly increasing ( or decreasing ) order.
In other words, in order to request resource Rj, a process must first release all Ri such that i >= j.
One big challenge in this scheme is determining the relative ordering of the different resources
DEADLOCK AVOIDANCE
The general idea behind deadlock avoidance is to prevent deadlocks from ever happening, by
preventing at least one of the aforementioned conditions.
This requires more information about each process, AND tends to lead to low device utilization. (
I.e. it is a conservative approach. )
In some algorithms the scheduler only needs to know the maximum number of each resource that a
process might potentially use. In more complex algorithms the scheduler can also take advantage of
the schedule of exactly what resources may be needed in what order.
When a scheduler sees that starting a process or granting resource requests may lead to future
deadlocks, then that process is just not started or the request is not granted.
A resource allocation state is defined by the number of available and allocated resources, and the
maximum requirements of all processes in the system.
57
Page
A state is safe if the system can allocate all resources requested by all processes ( up to their stated
maximums ) without entering a deadlock state.
More formally, a state is safe if there exists a safe sequence of processes { P0, P1, P2, ..., PN } such
that all of the resource requests for Pi can be granted using the resources currently allocated to Pi
and all processes Pj where j < i. ( I.e. if all the processes prior to Pi finish and free up their
resources, then Pi will be able to finish also, using the resources that they have freed up. )
If a safe sequence does not exist, then the system is in an unsafe state, which MAY lead to deadlock.
( All safe states are deadlock free, but not all unsafe states lead to deadlocks. )
For example, consider a system with 12 tape drives, allocated as follows. Is this a safe state? What is
the safe sequence?
P0 10 5
P1 4 2
P2 9 2
What happens to the above table if process P2 requests and is granted one more tape drive?
Key to the safe state approach is that when a request is made for resources, the request is granted
only if the resulting allocation state is a safe one.
If resource categories have only single instances of their resources, then deadlock states can be
detected by cycles in the resource-allocation graphs.
In this case, unsafe states can be recognized and avoided by augmenting the resource-allocation
graph with claim edges, noted by dashed lines, which point from a process to a resource that it
may request in the future.
In order for this technique to work, all claim edges must be added to the graph for any particular
process before that process is allowed to request any resources. ( Alternatively, processes may only
make requests for resources for which they have already established claim edges, and claim edges
58
The resulting resource-allocation graph would have a cycle in it, and so the request cannot be
granted.
Banker's Algorithm
For resource categories that contain more than one instance the resource-allocation graph method
does not work, and more complex (and less efficient) methods must be chosen.
The Banker's Algorithm gets its name because it is a method that bankers could use to assure that
when they lend out resources they will still be able to satisfy all their clients. (A banker won't loan
out a little money to start building a house unless they are assured that they will later be able to
loan out the rest of the money to finish the house.)
When a process starts up, it must state in advance the maximum allocation of resources it may
request, up to the amount available on the system.
When a request is made, the scheduler determines whether granting the request would leave the
system in a safe state. If not, then the process must wait until the request can be granted safely.
The banker's algorithm relies on several key data structures: (where n is the number of processes
and m is the number of resource categories.)
o Available[m] indicates how many resources are currently available of each type.
o Max[n][m] indicates the maximum demand of each process of each resource.
o Allocation[n][m] indicates the number of each resource category allocated to each process.
o Need[n][m] indicates the remaining resources needed of each type for each process. (Note
59
Safety Algorithm
In order to apply the Banker's algorithm, we first need an algorithm for determining whether or not
a particular state is safe.
This algorithm determines if the current state of a system is safe, according to the following steps:
1. Let Work and Finish be vectors of length m and n respectively.
Work is a working copy of the available resources, which will be modified during
the analysis.
Finish is a vector of booleans indicating whether a particular process can finish. (or
has finished so far in the analysis.)
Initialize Work to Available, and Finish to false for all elements.
2. Find an i such that both (A) Finish[i] == false, and (B) Need[i] < Work. This process has not
finished, but could with the given available working set. If no such i exists, go to step 4.
3. Set Work = Work + Allocation[i], and set Finish[i] to true. This corresponds to process i
finishing up and releasing its resources back into the work pool. Then loop back to step 2.
4. If finish[i] == true for all i, then the state is a safe state, because a safe sequence has been
found.
( JTB's Modification:
1. In step 1. instead of making Finish an array of booleans initialized to false, make it an array
of ints initialized to 0. Also initialize an int s = 0 as a step counter.
2. In step 2, look for Finish[i] == 0.
3. In step 3, set Finish[i] to ++s. S is counting the number of finished processes.
4. For step 4, the test can be either Finish[i] > 0 for all i, or s >= n. The benefit of this method is
that if a safe state exists, then Finish[ ] indicates one safe sequence ( of possibly many. ) )
Now that we have a tool for determining if a particular state is safe or not, we are now ready to look
at the Banker's algorithm itself.
This algorithm determines if a new request is safe, and grants it only if it is safe to do so.
When a request is made (that does not exceed currently available resources), pretend it has been
granted, and then see if the resulting state is a safe one. If so, grant the request, and if not, deny the
request, as follows:
1. Let Request[n][m] indicate the number of resources of each type currently requested by
processes. If Request[i] > Need[i] for any process i, raise an error condition.
2. If Request[i] > Available for any process i, then that process must wait for resources to
become available. Otherwise the process can continue to step 3.
3. Check to see if the request can be granted safely, by pretending it has been granted and then
seeing if the resulting state is safe. If so, grant the request, and if not, then the process must
wait until its request can be granted safely.The procedure for granting a request (or
pretending to for testing purposes) is:
Available = Available - Request
Allocation = Allocation + Request
Need = Need - Request
An Illustrative Example
And now consider what happens if process P1 requests 1 instance of A and 2 instances of C. (
Request[ 1 ] = ( 1, 0, 2 ) )
What about requests of ( 3, 3,0 ) by P4? or ( 0, 2, 0 ) by P0? Can these be safely granted? Why or
why not?
DEADLOCK DETECTION
If deadlocks are not avoided, then another approach is to detect when they have occurred and
recover somehow.
In addition to the performance hit of constantly checking for deadlocks, a policy / algorithm must
be in place for recovering from deadlocks, and there is potential for lost work when processes must
be aborted or have their resources preempted.
If each resource category has a single instance, then we can use a variation of the resource-
allocation graph known as a wait-for graph.
A wait-for graph can be constructed from a resource-allocation graph by eliminating the resources
and collapsing the associated edges, as shown in the figure below.
An arc from Pi to Pj in a wait-for graph indicates that process Pi is waiting for a resource that
process Pj is currently holding.
61
Page
Figure 7.9 - (a) Resource allocation graph. (b) Corresponding wait-for graph
The detection algorithm outlined here is essentially the same as the Banker's algorithm, with two
subtle differences:
o In step 1, the Banker's Algorithm sets Finish[i] to false for all i. The algorithm presented
here sets Finish[i] to false only if Allocation[i] is not zero. If the currently allocated
resources for this process are zero, the algorithm sets Finish[i] to true. This is essentially
assuming that IF all of the other processes can finish, then this process can finish also.
Furthermore, this algorithm is specifically looking for which processes are involved in a
deadlock situation, and a process that does not have any resources allocated cannot be
involved in a deadlock, and so can be removed from any further consideration.
o Steps 2 and 3 are unchanged
o In step 4, the basic Banker's Algorithm says that if Finish[i] == true for all i, that there is no
deadlock. This algorithm is more specific, by stating that if Finish[i] == false for any process
Pi, then that process is specifically involved in the deadlock which has been detected.
( Note: An alternative method was presented above, in which Finish held integers instead of
booleans. This vector would be initialized to all zeros, and then filled with increasing integers as
processes are detected which can finish. If any processes are left at zero when the algorithm
completes, then there is a deadlock, and if not, then the integers in finish describe a safe sequence.
To modify this algorithm to match this section of the text, processes with allocation = zero could be
filled in with N, N - 1, N - 2, etc. in step 1, and any processes left with Finish = 0 in step 4 are the
deadlocked processes. )
Consider, for example, the following state, and determine if it is currently deadlocked:
62
Page
Now suppose that process P2 makes a request for an additional instance of type C, yielding the
state shown below. Is the system now deadlocked?
Detection-Algorithm Usage
and determine when the deadlock occurred and what processes caused the initial deadlock.
Unfortunately I'm not certain that breaking the original deadlock would then free up the
Page
Process Termination
Two basic approaches, both of which recover resources allocated to terminated processes:
o Terminate all processes involved in the deadlock. This definitely solves the deadlock, but at
the expense of terminating more processes than would be absolutely necessary.
o Terminate processes one by one until the deadlock is broken. This is more conservative, but
requires doing deadlock detection after each step.
In the latter case there are many factors that can go into deciding which processes to terminate
next:
1. Process priorities.
2. How long the process has been running, and how close it is to finishing.
3. How many and what type of resources is the process holding. ( Are they easy to preempt
and restore? )
4. How many more resources does the process need to complete.
5. How many processes will need to be terminated
6. Whether the process is interactive or batch.
7. ( Whether or not the process has made non-restorable changes to any resource. )
Resource Preemption
When preempting resources to relieve deadlock, there are three important issues to be addressed:
1. Selecting a victim - Deciding which resources to preempt from which processes involves
many of the same decision criteria outlined above.
2. Rollback - Ideally one would like to roll back a preempted process to a safe state prior to
the point at which that resource was originally allocated to the process. Unfortunately it can
be difficult or impossible to determine what such a safe state is, and so the only safe
rollback is to roll back all the way back to the beginning. ( I.e. abort the process and make it
start over. )
3. Starvation - How do you guarantee that a process won't starve because its resources are
constantly being preempted? One option would be to use a priority system, and increase the
priority of a process every time its resources get preempted. Eventually it should get a high
enough priority that it won't get preempted any more.
64
Page
Semaphores: Semaphores are a synchronization tool used to control access to shared resources by
multiple processes. Semaphores are essentially counters that are used to regulate access to shared
resources.
Mutexes: Mutexes (short for "mutual exclusion") are a synchronization mechanism used to ensure
that only one process can access a shared resource at a time.
Monitors: Monitors are a synchronization mechanism used to regulate access to shared resources
in a multi-process environment. A monitor provides a mechanism for processes to request and
release ownership of a shared resource.
Condition Variables: Condition variables are used to coordinate access to shared resources by
multiple processes. A process waits on a condition variable until another process signals that it can
proceed.
Each of these synchronization methods has its own advantages and disadvantages, and the choice of a
particular method depends on the specific requirements of the application. In general, the use of
synchronization methods in IPC ensures that shared resources are accessed in a safe and controlled
manner, and helps to prevent conflicts and race conditions.
Entry Section: It is a step in the process that determines whether or not a process may begin.
Critical Section: This section enables a single process to access and modify a shared variable.
Exit Section: Other processes waiting in the Entry Section are able to enter the Critical Sections
through the Exit Section. It also ensures that a process that has completed its execution gets deleted
via this section.
Remainder Section: The Remainder Section refers to the rest of the code that isn't in the Critical,
Entry, or Exit sections.
65
Page
A solution to the critical-section problem must satisfy the following three requirements:
1. Mutual Exclusion:
RACE CONDITIONS
Each of the processes has some sharable resources and some non-shareable resources. The sharable
resources can be shared among the cooperating processes. The non-cooperating processes don’t need to
share the resources.
When we synchronize the processes and the synchronization is not proper then the race condition occurs.
We can define the race condition as follows;
A race condition is a condition when there are many processes and every process shares the data with each
other and accessing the data concurrently, and the output of execution depends on a particular sequence in
which they share the data and access.
Here are some examples of race conditions:
Race conditions can lead to unexpected or inconsistent results, or even system crashes.
Light switches
o A light switch can be one example of a race condition. For example, if multiple light switches
are connected to a common ceiling light, moving either switch from its current position
turns the light off.
Tube light
o A tube light with multiple switches is another example of a race condition.
Banking application
o A common example of a race condition is a banking application where multiple users
attempt to withdraw funds from the same account simultaneously.
Check-and-open process
o A file is locked out for other processes only if it is already in the open state. This process is
called the check-and-open process and during this time it is impossible to lock a file.
Check-then-act race conditions
o A snippet of code that represents the critical section where multiple threads can access the
shared resource, which is the map, is an example of a check-then-act race condition.
MUTUAL EXCLUSION
A way of making sure that if one process is using a shared modifiable data (Critical Section), the
other processes will be excluded from doing the same thing.
Formally, while one process executes the shared variable, all other processes desiring to do so at
the same time moment should be kept waiting; when that process has finished executing the shared
variable, one of the processes waiting; while that process has finished executing the shared
variable, one of the processes waiting to do so should be allowed to proceed. In this fashion, each
process executing the shared data (variables) excludes all others from doing so simultaneously.
This is called Mutual Exclusion.
Note that mutual exclusion needs to be enforced only when processes access shared modifiable
data - when processes are performing operations that do not conflict with one another they should
be allowed to proceed concurrently.
Below are the solutions to Mutual Exclusion Problem
1. Software Solutions: Dekker’s algorithm, Peterson algorithm, bakery’s algorithm
2. Hardware Solutions: Special machine Instruction
3. Operating System Solutions: Semaphores, Mutex
PETERSON’S SOLUTION
A classic software-based solution to the critical-section problem known as Peterson’s solution. Because of
the way modern computer architectures perform basic machine language instructions, such as load and
store, there are no guarantees that Peterson’s solution will work correctly on such architectures.
However, we present the solution because it provides a good algorithmic description of solving the critical-
section problem and illustrates some of the complexities involved in designing software that addresses the
67
int turn;
Peterson’s Solution is a classical software based solution to the critical section problem. In Peterson’s
solution, we have two shared variables:
boolean flag[i]: Initialized to FALSE, initially no one is interested in entering the critical section
int turn: The process whose turn is to enter the critical section.
Explanation:
1. Mutual exclusion is preserved
2. The progress requirement is satisfied
3. The bounded –waiting requirement is met.
P0 P1
while(1) while(1)
{ {
flag[0]=T flag[1]=T
turn=1; turn=0;
while (turn==1 && flag[1]==T); while (turn==0 && flag[0]==T);
critical section critical section
flag[0]=F flag[1]=F
} }
SYNCHRONIZATION HARDWARE:
There are three hardware approaches to solve process synchronization problems:
1. TestAndSet()
2. Swap()
1. Test and Set:
2. Swap():
remainder section
} }
Page
SEMAPHORES
Dijkstra proposed the concept of semaphore in 1965. Semaphore provides general purpose solution to
impose mutual exclusion among concurrently executing processes, where many processes want to execute
in their critical section but only one at a time is allowed and rest all other are excluded.
A semaphore basically consists of an integer variable S, shared by processes.
S is a protected variable that can only be accessed and manipulate by two operation: wait() and signal()
originally defined P( for wait) and V(for signal) by Dijkstra.
Properties of semaphore:
1. It is simple and always have a non-negative integer value
2. Works with many processes
3. Can have many different critical sections with different semaphores
4. Each critical section has unique access semaphores.
5. Can permit multiple processes into critical section at once, if desirable.
6. Solution to critical section
7. Act as resource management
8. It also decide the order of execution among the process( n-process)
Usage of semaphore
1. Counting semaphore
2. Binary semaphore
1. Counting semaphore:
2. Binary semaphore:
The binary semaphores are like counting semaphores but their value is restricted to 0 and 1. The wait
operation only works when the semaphore is 1 and the signal operation succeeds when semaphore is
0. It is sometimes easier to implement binary semaphores than counting semaphores.
Advantages of Semaphores
Some of the advantages of semaphores are as follows:
Semaphores allow only one process into the critical section. They follow the mutual exclusion
principle strictly and are much more efficient than some other methods of synchronization.
There is no resource wastage because of busy waiting in semaphores as processor time is not
wasted unnecessarily to check if a condition is fulfilled to allow a process to access the critical
section.
Semaphores are implemented in the machine independent code of the microkernel. So they are
machine independent.
Disadvantages of Semaphores
Some of the disadvantages of semaphores are as follows:
Semaphores are complicated so the wait and signal operations must be implemented in the correct
order to prevent deadlocks.
Semaphores are impractical for last scale use as their use leads to loss of modularity. This happens
because the wait and signal operations prevent the creation of a structured layout for the system.
Semaphores may lead to a priority inversion where low priority processes may access the critical
section first and high priority processes later.
Only one thread at a time can take the ownership of a mutex and apply the lock. Once it done utilising the
Page
Mutex is very different from Semaphores, please read Semaphores here and then read the difference
between mutex and semaphores here.
1. Mutex is Binary in nature
2. Operations like Lock and Release are possible
3. Mutex is for Threads, while Semaphores are for processes.
4. Mutex works in user-space and Semaphore for kernel
5. Mutex provides locking mechanism
6. A thread may acquire more than one mutex
7. Binary Semaphore and mutex are different
Bounded-Buffer Problem
Readers and Writers Problem
Dining-Philosophers Problem
BOUNDED-BUFFER PROBLEM (PRODUCER CONSUMER PROBLEM)
Producer consumer problem is one classic example of mutual exclusion, process synchronisation using
semaphores. It basically synchronises data production and consumption happening simultaneously in a
system where there is fixed amount of storage size. The system has the following:
1. Producer
2. Consumer
3. Storage (Buffer)bound of size n
READERS-WRITERS PROBLEM
This is a synchronisation problem which is used to test newly proposed synchronisation scheme.
The problem statement is, if a database or file is to be shared among several concurrent process, there can
be broadly 2 types of users:
1. Readers – Reader are those processes/users which only read the data
74
2. Writers – Writers are those processes which also write, that is, they change the data.
Page
Highlights
Solution
Variables used:
1. Mutex – mutex (used for mutual exclusion, when readcount is changed)
o initialised as 1
75
signal (Semaphore s)
{
s = s + 1;
}
In above code: semicolon after while, which results in the while loop getting executed again and again.
Until s value is non-zero.
Writers problem
while(TRUE)
{
wait(wrt);
/* writer does some write operation */
signal(wrt);
}
1. Writer wants the access to critical section i.e. wants to perform the writing
2. First wait(wrt) value is checked
76
If a process wanting to only read shared data, request reader-writer lock in read mode. A process waiting
to only write on shared data must request the lock in write mode.
Page
Thinking
Eating
Whenever the philosophers want to eat. He obviously will use two chopsticks together.
o So to eat both chopsticks on his right and left must be free.
Whenever he is thinking
o He must put down both the chopsticks back at the table.
Deadlock condition
A deadlock condition may arise here, consider if all the philosophers get hungry simultaneously together
and they pick up one chopstick on their left.
In this case they will wait indefinitely for their 2nd chopstick(right chopstick) and the deadlock will be
there forever.
Rules and Solution
If a philosopher decides to eat:
Even Odd:
Page
MONITORS
Monitors are used for process synchronization. With the help of programming languages, we can use a
monitor to achieve mutual exclusion among the processes. Example of monitors: Java Synchronized
methods such as Java offers notify() and wait() constructs.
In other words, monitors are defined as the construct of programming language, which helps in controlling
shared data access.
The Monitor is a module or package which encapsulates shared data structure, procedures, and the
synchronization between the concurrent procedure invocations.
Characteristics of Monitors.
1. Inside the monitors, we can only execute one process at a time.
2. Monitors are the group of procedures, and condition variables that are merged together in a special
type of module.
3. If the process is running outside the monitor, then it cannot access the monitor’s internal variable.
But a process can call the procedures of the monitor.
4. Monitors offer high-level of synchronization
79
Components of Monitor
There are four main components of the monitor:
Initialization
Private data
Monitor procedure
Monitor entry queue
Initialization: Initialization comprises the code, and when the monitors are created, we use this code
exactly once.
Private Data: Private data is another component of the monitor. It comprises all the private data, and the
private data contains private procedures that can only be used within the monitor. So, outside the monitor,
private data is not visible.
Monitor Procedure: Monitors Procedures are those procedures that can be called from outside the
monitor.
Monitor Entry Queue: Monitor entry queue is another essential component of the monitor that includes
all the threads, which are called procedures.
Syntax of monitor
Monitor monitorName{
variables_declaration;
condition_variables;
procedure p1{ ... };
80
...
Advantages of Monitor
It makes the parallel programming easy, and if monitors are used, then there is less error-prone as
compared to the semaphore.
81
Page
Monitors Semaphore
In monitors, wait always block the caller. In semaphore, wait does not always block the caller.
Independent process.
Co-operating process.
An independent process is not affected by the execution of other processes while a cooperating process can
be affected by other executing processes. Though one can think that those processes, which are running
independently, will execute very efficiently, in reality, there are many situations when co-operative nature
can be utilised for increasing computational speed, convenience and modularity.
Inter process communication (IPC) is a mechanism which allows processes to communicate with each
other and synchronize their actions. The communication between these processes can be seen as a method
of cooperation between them. Processes can communicate with each other through both:
4. Shared Memory
5. Message passing
PIPES
Pipes are a simple form of shared memory that allows two processes to communicate with each
other.
It is a half duplex method (or one way communication) used for IPC between two related processes.
One process writes data to the pipe, and the other process reads data from the pipe.
It is like a scenario like filling water with a tap into a bucket. The filling process is writing into the
pipe and the reading process is retrieving from the pipe.
Pipes can be either named or anonymous, depending on whether they have a unique name or not.
Named pipes are a type of pipe that has a unique name, and can be accessed by multiple processes.
Named pipes can be used for communication between processes running on the same host or
between processes running on different hosts over a network.
Anonymous pipes, on the other hand, are pipes that are created for communication between a
parent process and its child process. Anonymous pipes are typically used for one-way
communication between processes, as they do not have a unique name and can only be accessed by
the processes that created them.
82
Page
In parent process use system call write() to write message from one process to another process.
Working of FIFO
Page
Creation:
Characteristics of FIFO
Named:
o FIFOs have names, allowing unrelated processes to locate and use them.6
First-In, First-Out:
o Data is processed in the order it arrives.
Blocking:
o Operations can block, which is essential for synchronization.
File System Presence:
o FIFOs appear as files in the file system.
Usage of FIFO
FIFOs are useful when you need to transfer data between independent processes that don't share a
common ancestor.
They are often used in client-server applications or in situations where you need to pipe data
between different programs.
SHARED MEMORY:
Shared memory is a region of memory that is accessible to multiple processes. This allows
processes to communicate with each other by reading and writing data from the shared memory
region.
Shared memory is a fast and efficient way for processes to communicate, but it can be difficult to
use if the processes are not carefully synchronized.
There are two main types of shared memory:
o Anonymous shared memory: Anonymous shared memory is not associated with any file
or other system object. It is created by the operating system and is only accessible to the
processes that created it.
o Mapped shared memory: Mapped shared memory is associated with a file or other system
object. It is created by mapping a file into the address space of one or more processes.
Multiple processes can access a common shared memory. Multiple processes communicate by shared
memory, where one process makes changes at a time and then others view the change. Shared memory
does not use kernel.
84
Page
MESSAGE PASSING
Message passing is a method of Inter Process Communication in OS. It involves the exchange of
messages between processes, where each process sends and receives messages to coordinate its
activities and exchange data with other processes.
Processes can communicate without any shared variables; therefore it can be used in a distributed
environment on a network.
In message passing, each process has a unique identifier, known as a process ID, and messages are
sent from one process to another using this identifier. When a process sends a message, it specifies
the recipient process ID and the contents of the message, and the operating system is responsible
for delivering the message to the recipient process. The recipient process can then retrieve the
contents of the message and respond, if necessary.
Message passing in shared memory has a number of advantages over other IPC mechanisms. First,
it is very fast, as messages are simply copied from one process's address space to another. Second,
it is very flexible, as any type of data can be shared between processes. Third, it is relatively easy to
implement, as it does not require any special support from the operating system.
However, message passing in shared memory also has some disadvantages. First, it can be difficult
to ensure that messages are delivered in the correct order. Second, it can be difficult to manage the
size of the message queue. Third, it can be difficult to port to other platforms, as the
implementation of shared memory can vary from one operating system to another.
MESSAGE QUEUES
Message queues are a more advanced form of pipes.
They allow processes to send messages to each other, and they can be used to communicate
between processes that are not running on the same machine.
Message queues are a good choice for communication between processes that need to be decoupled
from each other.
85
Page
In Message Queue IPC, each message has a priority associated with it, and messages are retrieved
from the queue in order of their priority. This allows processes to prioritize the delivery of
important messages and ensures that critical messages are not blocked by less important messages
in the queue.
Writing into shared memory by one process with different data packets and reading from it by
multiple processes, i.e., as per message type
Message Queue IPC provides a flexible and scalable method of communication between processes,
as messages can be sent and received asynchronously, allowing processes to continue executing
while they wait for messages to arrive.
The main disadvantage of Message Queue IPC is that it can introduce additional overhead, as
messages must be copied between address spaces, and the queue must be managed by the
operating system to ensure that it remains synchronized and consistent across all processes.
We have linked list to store messages in a kernel of OS and a message queue is identified using "message
queue identifier".
A remote procedure call is an interprocess communication technique that is used for client-server based
Page
Remote procedure calls support process oriented and thread oriented models.
The internal message passing mechanism of RPC is hidden from the user.
The effort to re-write and re-develop the code is minimum in remote procedure calls.
Remote procedure calls can be used in distributed environment as well as the local environment.
Many of the protocol layers are omitted by RPC to improve performance.
The remote procedure call is a concept that can be implemented in different ways. It is not a
standard.
There is no flexibility in RPC for hardware architecture. It is only interaction based.
There is an increase in costs because of remote procedure call.
87
Page
Memory consists of a large array of bytes, each with its own address. The CPU fetches instructions
from memory according to the value of the program counter.
Main memory and the registers built into the processor itself are the only general-purpose storage
that the CPU can access directly.
Registers that are built into the CPU are generally accessible within one cycle of the CPU clock.
A memory access may take many cycles of the CPU clock. In such cases, the processor normally
needs to stall, since it does not have the data required to complete the instruction.
The remedy is to add fast memory between the CPU and main memory, typically on the CPU chip
for fast access called as CACHE.
MEMORY PROTECTION:
For proper system operation we must protect the operating system from access by user processes.
Each process has a separate memory space. Separate per-process memory space protects the
processes from each other.
The hardware protection of memory is provided by two registers
o Base Register
o Limit Register
The base register holds the smallest legal physical memory address, called the starting address of
the process.
The Limit register specifies the size of range of the process.
If the base register holds300040 and the limit register is 120900, then the program can legally
access all addresses from 300040 through 420939
Protection of memory space is accomplished by having the CPU hardware compare every address
generated in user mode with the registers.
Any attempt by a program executing in user mode to access operating-system memory or other
users’ memory results in a trap to the operating system, resulting in addressing error.
The base and limit registers can be loaded only by the operating system into the CPU hardware.
88
Page
This scheme prevents a user program from modifying the code or data structures of either the
operating system or other users.
The address generated by the CPU for a process should lie between the Base address of the process
and base + Limit of the process, Else the hardware sends an interrupt to the OS.
ADDRESS BINDING:
Address binding is the process of mapping the program's logical or virtual addresses to
corresponding physical or main memory addresses.
Addresses in the source program are generally symbolic.
A compiler typically binds these symbolic addresses to relocatable addresses.
The linkage editor or loader in turn binds the relocatable addresses to absolute addresses
Each binding is a mapping from one address space to another.
The binding of instructions and data to memory addresses can be done in three ways.
1) Compile time. If you know at compile time where the process will reside in memory, then absolute
code can be generated.
2) Load time. If it is not known at compile time where the process will reside in memory, then the
89
An address generated by the CPU is commonly referred to as a logical address. which is also called
as virtual address
The set of all logical addresses generated by a program is a logical address space.
An address seen by the memory unit—that is, the one loaded into the memory-address register of
the memory—is commonly referred to as a physical address.
The set of all physical addresses corresponding to these logical addresses is a physical address
space.
The run-time mapping from virtual to physical addresses is done by a device called the memory-
management unit (MMU).
DYNAMIC LOADING:
Dynamic Loading is the process of loading a routine only when it is called or needed during
runtime.
Initially all routines are kept on disk in a relocatable load format.
The main program is loaded into memory and is executed. When a routine needs to call another
routine, the calling routine first checks to see whether the other routine has been loaded. If it has
not, the relocatable linking loader is called to load the desired routine into memory.
The advantage of dynamic loading is that a routine is loaded only when it is needed.
This method is particularly useful when large amounts of code are needed to handle infrequently
90
In Dynamic linking the linking of system libraries are postponed until execution time.
Static Linking combines the system libraries to the user program at the time of compilation.
Dynamic linking saves both the disk space and the main memory space.
The libraries can be replaced by a new version and all the programs that reference the library will
use the new version. This system is called as Shared libraries which can be done with dynamic
linking.
SWAPPING:
The system maintains a ready queue consisting of all processes whose memory images are on the
backing store or in memory and are ready to run.
Whenever the CPU scheduler decides to execute a process, it calls the dispatcher. The dispatcher
checks to see whether the next process in the queue is in memory.
If it is not, and if there is no free memory region, the dispatcher swaps out a process currently in
memory and swaps in the desired process.
A variant of swapping policy is used for priority based scheduling algorithms. If a higher priority
process arrives and want service the memory manager can then swap the lower priority process
Page
The main memory must accommodate both the operating system and the various user processes
The memory is usually divided into two partitions: one for the resident operating system and one
for the user processes.
In Multiprogramming several user processes to reside in memory at the same time.
The OS need to decide how to allocate available memory to the processes that are in the input
queue waiting to be brought into memory.
In contiguous memory allocation, each process is contained in a single section of memory that is
contiguous to the section containing the next process.
MEMORY PROTECTION:
MEMORY ALLOCATION:
In Contiguous memory allocation the memory can be allocated in two ways
1. Fixed partition scheme
2. Variable partition scheme
92
In the variable-partition scheme, the operating system keeps a table indicating which parts of
memory are available and which are occupied.
Initially, all memory is available for user processes and is considered one large block of available
memory, a hole.
When a process is allocated space, it is loaded into memory, and it can then compete for CPU time.
When a process terminates, it releases its memory, which the operating system may then fill with
another process from the input queue. Os will have a list of available block sizes and an input
queue. The operating system can order the input queue according to a scheduling algorithm.
Memory is allocated to processes until, finally, the memory requirements of the next process
cannot be satisfied—that is, no available block of memory (or hole) is large enough to hold that
process.
When a process arrives and needs memory, the system searches the set for a hole that is large
enough for this process.
If the hole is too large, it is split into two parts. One part is allocated to the arriving process; the
other is returned to the set of holes.
When a process terminates, it releases its block of memory, which is then placed back in the set of
holes. If the new hole is adjacent to other holes, these adjacent holes are merged to form one larger
hole.
The system may need to check whether there are processes waiting for memory and whether this
newly freed and recombined memory could satisfy the demands of any of these waiting processes.
This procedure is a particular instance of the general dynamic storage allocation problem
Next fit: Same as first fit but start search always from last allocated hole.
Question # 1
Consider a swapping system in which memory consists of the following hole sizes in memory order: 10K,
4K, 20K, 18K, 7K, 9K, 12K and 15K. Which hole is taken for successive segment requests of (a) 12K, (b)
10K, (c) 9K for first fit? Repeat the question for best fit, worst fit and next fit.
Solution:
Question # 2
Given memory partitions of 100K, 500K, 200K, 300K and 600K (in order), how would each of the First-fit,
Best-fit, and Worst-fit algorithms place processes of 212K, 417K, 112K and 624K (in order)? Which
algorithm makes the most efficient use of memory?
Solution:
94
Page
Both the first-fit and best-fit strategies suffer from external fragmentation.
EXTERNAL FRAGMENTATION: As processes are loaded and removed from memory, the free memory
space is broken into little pieces. External fragmentation exists when there is enough total memory space
to satisfy a request but the available spaces are not contiguous, so that the memory cannot be allocated to
the process.
COMPACTION: One solution to the problem of external fragmentation is compaction. The goal is to shuffle
the memory contents so as to place all free memory together in one large block.
50 PERCENT RULE: The analysis of first fit, reveals that given N allocated blocks, another 0.5 N blocks will
be lost to fragmentation. That is, one-third of memory may be unusable! This property is known as the 50-
percent rule.
1. SEGMENTATION:
Segmentation is a memory-management scheme that supports the programmer view of memory.
A logical address space is a collection of segments.
Each segment has a name and a length.
95
The logical addresses specify both the segment name and the offset within the segment. Each address is
Page
SEGMENTATION HARDWARE:
The programmer can refer to objects in the program by a two-dimensional address (segment
number and offset); the actual physical memory a one dimensional sequence of bytes.
The two-dimensional user-defined addresses should be mapped into one-dimensional physical
addresses.
The mapping of logical address to physical address is done by a table called segment table.
Each entry in the segment table has a segment base and a segment limit.
The segment base contains the starting physical address where the segment resides in memory
The segment limit specifies the length of the segment.
96
Page
A logical address consists of two parts: a segment number, s, and an offset into that segment, d.
The segment number is used as an index to the segment table. The offset d of the logical address
must be between 0 and the segment limit.
If it is not between 0 and limit then hardware trap to the operating system (logical addressing
attempt beyond end of segment).
When an offset is legal, it is added to the segment base to produce the address in physical memory
of the desired byte.
The segment table is an array of base–limit register pairs.
Segmentation can be combined with paging.
Example: Consider five segments numbered from 0 through 4. The segment table has a separate entry for each
segment, giving the beginning address of the segment in physical memory (or base) and the length of that
segment (or limit).
The Segment 2 is 400 bytes long and begins at location 4300. Thus, a reference to byte 53 of
segment 2 is mapped onto location 4300 + 53 = 4353.
A reference to segment 3, byte 852, is mapped to 3200 (the base of segment 3) + 852 = 4052.
A reference to byte 1222 of segment 0 would result in a trap to the operating system, as this
segment is only 1,000 bytes long.
Working-
In segmented paging,
97
Page
Process is first divided into segments and then each segment is divided into pages.
Following steps are followed to translate logical address into physical address-
Step-01:
1. Segment Number
2. Page Number
3. Page Offset
Segment Number specifies the specific segment from which CPU wants to reads the data.
Page Number specifies the specific page of that segment from which CPU wants to read the data.
Page Offset specifies the specific word on that page that CPU wants to read.
Step-02:
For the generated segment number, corresponding entry is located in the segment table.
Segment table provides the frame number of the frame storing the page table of the referred
segment.
The frame containing the page table is located.
Step-03:
For the generated page number, corresponding entry is located in the page table.
Page table provides the frame number of the frame storing the required page of the referred
segment.
The frame containing the required page is located.
98
Step-04:
Page
The frame number combined with the page offset forms the required physical address.
For the generated page offset, corresponding word is located in the page and read.
Diagram-
The following diagram illustrates the above steps of translating logical address into physical address-
Advantages:
Disadvantages:
PAGING HARDWARE:
Every address generated by the CPU is divided into two parts: a page number (p) and a page offset
(d).
The page number is used as an index into a page table.
The page table contains the base address of each page in physical memory.
This base address is combined with the page offset to define the physical memory address that is
sent to the memory unit.
The page size is defined by the hardware. The size of a page is a power of 2, varying between 512 bytes and
1 GB per page.
If the size of the logical address space is 2m, and a page size is 2n bytes, then the high-order m− n bits of a
logical address designate the page number, and the n low-order bits designate the page offset.
The logical address is given by
Here p is an index into the page table and d is the displacement within the page.
PAGING MODEL:
100
Page
PAGING EXAMPLE:
Consider the memory with the logical address, n= 2 and m = 4. Using a page size of 4 bytes and a
physical memory of 32 bytes
Logical address 0 is page 0, offset 0. Indexing into the page table, we find that page 0 is in frame 5.
Thus, logical address 0 maps to physical address 20 [= (5 × 4) + 0].
101
Each page of the process needs one frame. Thus, if the process requires n pages, at least n frames
must be available in memory.
If n frames are available, they are allocated to this arriving process.
The operating system is managing physical memory and knows the allocation details of physical
memory— which frames are allocated, which frames are available, how many total frames there
are, and so on.
This information is generally kept in a data structure called a frame table.
HARDWARE SUPPORT:
The hardware implementation of the page table can be done in several ways. The page table is
implemented as a set of dedicated registers if the size of the page table is too small.
If the size of the page table is too large then the page table is kept in main memory and a page table
base register is used to point to the page table.
When the page table is kept in main memory then two memory accesses are required to access a
byte.
One for accessing the page table entry, another one for accessing the byte.
Thus the overhead of accessing the main memory increases.
The standard solution to this problem is to use a special, small, fast lookup hardware cache called a
translation look-aside buffer (TLB).
102
Page
Each entry in the TLB consists of two parts: a key (or tag) and a value.
The TLB contains only a few of the page-table entries.
When a logical address is generated by the CPU, its page number is presented to the TLB. If the
page number is found (TLB HIT), its frame number is immediately available and is used to access
memory.
If the page number is not in the TLB (TLB miss), a memory reference to the page table must be
made. When the frame number is obtained, we can use it to access memory.
The percentage of times that the page number of interest is found in the TLB is called the hit ratio.
The access time of a byte is said to be effective when the TLB hit ratio is high.
Thus the effective access time is given by
Effective access time = TLB hit ratio* Memory access time +TLB miss ratio* (2*memory access time)
PROTECTION:
Memory protection in a paged environment is accomplished by protection bits associated with each
frame.
One bit can define a page to be read–write or read-only. When the physical address is being
computed, the protection bits can be checked to verify that no writes are being made to a read-only
page
One additional bit is generally attached to each entry in the page table: a valid–invalid bit. When
this bit is set to valid, the associated page is in the process’s logical address space and is thus a legal.
When the bit is set to invalid, the page is not in the process’s logical address space.
Page-table length register (PTLR), is used to indicate the size of the page table. This value is
checked against every logical address to verify that the address is in the valid range for the process
103
Page
VIRTUAL MEMORY:
Virtual memory is a memory management technique that allows the execution of processes that are
not completely in memory.
In some cases during the execution of the program the entire program may not be needed, such as
error conditions, menu selection options etc.
The virtual address space of a process refers to the logical view of how a process is stored in
memory.
The heap will grow upward in memory as it is used for dynamic memory allocation.
104
The stack will grow downward in memory through successive function calls.
The large blank space (or hole) between the heap and the stack is part of the virtual address space
but will require actual physical pages only if the heap or stack grows.
Page
Virtual address spaces that include holes are known as sparse address spaces.
ADVANTAGES:
One major advantage of this scheme is that programs can be larger than physical memory
Virtual memory also allows processes to share files easily and to implement shared memory.
Increase in CPU utilization and throughput.
Less I/O would be needed to load or swap user programs into memory
DEMAND PAGING:
Demand paging is the process of loading the pages only when they are demanded by the process
during execution. Pages that are never accessed are thus never loaded into physical memory.
A demand-paging system is similar to a paging system with swapping where processes reside in
secondary memory
105
Page
PAGE FAULT: If the process tries to access a page that was not brought into memory, then it is called as a
page fault.
Access to a page marked invalid causes a page fault.
The paging hardware, will notice that the invalid bit is set, causing a trap to the operating system.
PURE DEMAND PAGING: The process of executing a program with no pages in main memory is called as
pure demand paging. This never brings a page into memory until it is required.
The hardware to support demand paging is the same as the hardware for paging and swapping:
Page table. This table has the ability to mark an entry invalid through a valid–invalid bit or a special
value of protection bits.
Secondary memory. This memory holds those pages that are not present in main memory. The
secondary memory is usually a high-speed disk. It is known as the swap device, and the section of
disk used for this purpose is known as swap space.
With an average page-fault service time of 8 milliseconds and a memory access time of 200 nanoseconds,
the effective access time in nanoseconds is
Effective access time = (1 − p) × (200) + p (8 milliseconds)
= (1 − p) × 200 + p × 8,000,000
= 200 + 7,999,800 × p.
107
PAGE REPLACEMENT:
If no frames are free, two page transfers (one out and one in) are required. This situation effectively
doubles the page-fault service time and increases the effective access time accordingly.
This overhead can be reduced by using a modify bit (or dirty bit).
When this scheme is used, each page or frame has a modify bit associated with it in the hardware.
MODIFY BIT: The modify bit for a page is set by the hardware whenever any byte in the page is
written into, indicating that the page has been modified.
When we select a page for replacement, we examine its modify bit. If the bit is set, we know that the
page has been modified since it was read in from the disk. In this case, we must write the page to
the disk.
If the modify bit is not set, however, the page has not been modified since it was read into memory.
In this case, we need not write the memory page to the disk: it is already there.
Page 0 is the next reference and 0 is already in memory, we have no fault for this reference.
The first reference to 3 results in replacement of page 0, since it is now first in line.
Because of this replacement, the next reference, to 0, will fault. Page 1 is then replaced by page 0.
The process continues until all the pages are referenced.
Advantages:
The FIFO page-replacement algorithm is easy to understand and program
Disadvantages:
The Performance is not always good.
It Suffers from Belady’s Anomaly.
BELADY’S ANOMALY: The page fault increases as the number of allocated memory frame increases. This
unexpected result is called as Belady’s Anomaly.
Case 1: Frame=3
Page fault = 9
Case 2: Frame = 4
110
Page
Page fault = 10
Advantages:
Optimal replacement is much better than a FIFO algorithm
Disadvantage:
The optimal page-replacement algorithm is difficult to implement, because it requires future
knowledge of the reference string.
111
time.
Advantages:
The LRU policy is often used as a page-replacement algorithm and is considered to be good.
LRU replacement does not suffer from Belady’s anomaly.
Disadvantage:
The problem is to determine an order for the frames defined by the time of last use.
CONCEPT OF FILE:
• A file is a named collection of related information that is recorded on secondary storage such as
magnetic disks, magnetic tapes and optical disks.
• In general, a file is a sequence of bits, bytes, lines or records whose meaning is defined by the files
creator and user.
ATTRIBUTES OF A FILE
Following are some of the attributes of a file:
• Name. It is the only information which is in human-readable form.
• Identifier. The file is identified by a unique tag(number) within file system.
• Type. It is needed for systems that support different types of files.
• Location. Pointer to file location on device.
• Size. The current size of the file.
• Protection. This controls and assigns the power of reading, writing, executing.
• Time, date, and user identification. This is the data for protection, security, and usage monitoring.
FILE OPERATIONS
The operating system must do to perform basic file operations given below.
• Creating a file: Two steps are necessary to create a file. First, space in the file system must be found
for the file. Second, an entry for the new file must be made in the directory.
• Writing a file: To write a file, we make a system call specifying both the name of the file and the
information to be written to the file. Given the name of the file, the system searches the directory to
find the file's location. The system must keep a write pointer to the location in the file where the
next write is to take place. The write pointer must be updated whenever a write occurs.
• Reading a file: To read from a file, we use a system call that specifies the name of the file and where
(in memory) the next block of the file should be put. Again, the directory is searched for the
associated entry, and the system needs to keep a read pointer to the location in the file where the
next read is to take place. Once the read has taken place, the read pointer is updated.
• Repositioning within a file: The directory is searched for the appropriate entry, and the current-file-
position pointer is repositioned to a given value. Repositioning within a file need not involve any
actual I/O. This file operation is also known as a file seek.
• Deleting a file. To delete a file, we search the directory for the named file. Having found the
associated directory entry, we release all file space, so that it can be reused by other files, and erase
the directory entry.
• Protection: Access-control information determines who can do reading, writing, executing, and so
on.
• Truncating a file: The user may want to erase the contents of a file but keep its attributes. Rather
than forcing the user to delete the file and then recreate it, this function allows all attributes to
remain unchanged—except for file length—but lets the tile be reset to length zero and its file space
released.
In brief:
113
Page
File Types:
A common technique for implementing file types is to include the type as part of the file name. The name is
split into two parts—a name and an extension, usually separated by a period (Figure 11.3). In this way, the
user and the operating system can tell from the name alone what the type of a file is. Most operating
systems allow users to specify a file name as a sequence of characters followed by a period and terminated
by an extension made up of additional characters. Examples include resume.docx, server.c, and
ReaderThread.cpp.
114
Page
File Structure:
A File Structure should be according to a required format that the operating system can understand.
• A file has a certain defined structure according to its type.
• A text file is a sequence of characters organized into lines.
• A source file is a sequence of procedures and functions.
• An object file is a sequence of bytes organized into blocks that are understandable by the machine.
• When operating system defines different file structures, it also contains the code to support these
file structure. Unix, MS-DOS support minimum number of file structure.
The logical record size, physical block size, packing determines how many logical records are in each
physical block. The packing can be done by the user’s application program or OS. A file may be
considered a sequence of blocks. If each block were 512 bytes, a file of 1949 bytes would be allocated 4
blocks (2048 bytes). The last 99 bytes would be wasted. It is called internal fragmentation all file
systems suffer from internal fragmentation, the larger the block size, the greater the internal
fragmentation.
Files can be structured in several ways in which three common structures are given below with their short
description one by one.
File Structure 1
• Here, as we can see from the figure 1, the file is an unstructured sequence of bytes.
• Therefore, the OS doesn't care about what is in the file, as all it sees are bytes.
File Structure 2
• Now, as we can see from the figure 2 that shows the second structure of a file, where a file is a
sequence of fixed-length records where each with some internal structure.
• Central to the idea about a file being a sequence of records is the idea that read operation returns a
record and write operation just appends a record.
File Structure 3
• Now in the last structure of a file that you can see in the figure 3, a file basically consists of a tree of
records, not necessarily all the same length, each containing a key field in a fixed position in the
record. The tree is stored on the field, just to allow the rapid searching for a specific key.
115
Page
Sequential Access:
It is the simplest access method. Information in the file is processed in order i.e. one record after another. A
process can read all the data in a file in order starting from beginning but can’t skip & read arbitrarily from
any location. Sequential files can be rewound. It is convenient when storage medium was magnetic tape
rather than disk.
Eg : A file consisting of 100 records, the current position of read/write head is 45th record, suppose we
want to read the 75th record then, it access sequentially from 45, 46, 47 …….. 74, 75. So the read/write
head traverse all the records between 45 to 75.
Direct Access:
• A file is made up of fixed length-logical records that allow programs to read & write records rapidly
in no particular order.
• This method can be used when disk are used for storing files.
• This method is used in many applications e.g. database systems.
• If an airline customer wants to reserve a seat on a particular flight, the reservation program must
be able to access the record for that flight directly without reading the records before it.
• In a direct access file, there is no restriction in the order of reading or writing.
• For example, we can read block 14, then read block 50 & then write block 7 etc. Direct access files
are very useful for immediate access to large amount of information.
Indexed Access:
116
• In this method an index is created which contains a key field and pointers to the various blocks.
• To find an entry in the file for a key value, we first search the index and then use the pointer to
directly access a file and find the desired entry.
Page
DIRECTORY STRUCTURE:
• Sometimes the file system consisting of millions of files, at that situation it is very hard to manage
the files. To manage these files grouped these files and load one group into one partition. Each
partition is called a directory. A directory structure provides a mechanism for organizing many files
in the file system.
• Operation on the directories: the various operations that can be performed on directory are:
• Searching for a file: we need to search a directory structure to find the entry for a particular file.
Since files have symbolic names in a user-readable form and similar names may indicate a
relationship between files. We may want to able to find all files whose names match a particular
pattern.
• Create a file: new files are created and added to the directory.
• Delete a file: when we do not require to use a particular file, it is removed from the
• List a directory: when we want to list all the files in a particular directory, and the contents of
directory entry for each file in the list.
• Rename a file: Whenever we need to change the name of the file, we can change the name.
• Traverse the file system: in a directory structure, we may wish to access every directory, and every
file within a directory structure. Directory Structure: The most common schemes for defining the
structure of the directory are:
Single-level Directory:
It is the simplest directory structure. All files are contained in the same directory which is easy to support
and understand (figure 3)
117
Advantages:
Page
Disadvantages:
• There may chance of name collision because two files cannot have the same name.
• Searching will become time taking if the directory is large.
• The same type of files cannot be grouped together.
Two-level Directory:
• The disadvantage of single level directory is the confusion of files names between different users.
The solution for this problem is to create a directory for each user as shown in figure 4.
• In the two-level directory structure, each user has his own user files directory (UFD).
• Each user has similar structure but lists only the files of a single user.
• When user login, the system’s master file directory (MFD) is searched.
• The master file directory is indexed by user name or account number and each entry points to the
user directory for that user.
• When users refer to a particular file, only their own user file directory is searched.
• Thus different users may have files with the same name, as long as all file names within each user
file directory are unique.
Advantages:
• We can give full path like /User-name/directory-name.
• Different users can have same directory as well as file name.
• Searching of files become more easy due to path name and user-grouping.
Disadvantages:
• A user is not allowed to share files with other users.
• Still it not very scalable, two files of the same type cannot be grouped together in the same user.
Advantages:
• Very generalize, since full path name can be given.
• Very scalable, the probability of name collision is less.
• Searching becomes very easy, we can use both absolute path or relative
Disadvantages:
• Every file does not fit into the hierarchical directories.
• We cannot share files.
• It is inefficient, because accessing a file may go under multiple directories
119
Page
Disadvantages:
• We share the files via linking; in case of del
• Need to be cautions of dangling pointers when files are deleted.
FILE PROTECTION
Protection can be provided in many ways. For a single-user laptop system, we might provide protection by
locking the computer in a desk drawer or file cabinet. In a larger multiuser system, however, other
mechanisms are needed.
Types of Access
The need to protect files is a direct result of the ability to access files. Systems that do not permit access to
the files of other users do not need protection. Thus, we could provide complete protection by prohibiting
access. Alternatively, we could provide free access with no protection. Both approaches are too extreme for
general use. What is needed is controlled access.
Protection mechanisms provide controlled access by limiting the types of file access that can be made.
Access is permitted or denied depending on several factors, one of which is the type of access requested.
Several different types of operations may be controlled:
Read. Read from the file.
Write. Write or rewrite the file.
Execute. Load the file into memory and execute it.
Append. Write new information at the end of the file.
Delete. Delete the file and free its space for possible reuse.
List. List the name and attributes of the file.
Other operations, such as renaming, copying, and editing the file, may also be controlled.
For many systems, however, these higher-level functions may be implemented by a system program that
makes lower-level system calls.
Protection is provided at only the lower level. For instance, copying a file may be implemented simply by a
sequence of read requests. In this case, a user with read access can also cause the file to be copied, printed,
and so on.
Many protection mechanisms have been proposed. Each has advantages and disadvantages and must be
appropriate for its intended application. A small computer system that is used by only a few members of a
research group, for example, may not need the same types of protection as a large corporate computer that
is used for research, finance, and personnel operations.
Access Control
The most common approach to the protection problem is to make access dependent on the identity of the
user. Different users may need different types of access to a file or directory. The most general scheme to
implement identity dependent access is to associate with each file and directory an access-control list
(ACL) specifying user names and the types of access allowed for each user.
When a user requests access to a particular file, the operating system checks the access list associated with
that file. If that user is listed for the requested access, the access is allowed. Otherwise, a protection
violation occurs, and the user job is denied access to the file.
This approach has the advantage of enabling complex access methodologies. The main problem with access
lists is their length. If we want to allow everyone to read a file, we must list all users with read access. This
120
These problems can be resolved by use of a condensed version of the access list.
To condense the length of the access-control list, many systems recognize three classifications of users in
connection with each file:
Owner. The user who created the file is the owner.
Group. A set of users who are sharing the file and need similar access is a group, or work group.
Universe. All other users in the system constitute the universe.
The most common recent approach is to combine access-control lists with the more general (and easier to
implement) owner, group, and universe access control scheme just described. For example, Solaris uses the
three categories of access by default but allows access-control lists to be added to specific files and
directories when more fine-grained access control is desired.
To improve I/O efficiency, I/O transfers between memory and disk are performed in units of blocks. Each
block has one or more sectors. Depending on the disk drive, sector size varies from 32 bytes to 4,096 bytes;
the usual size is 512 bytes.
File systems provide efficient and convenient access to the disk by allowing data to be stored, located, and
retrieved easily. A file system poses two quite different design problems.
The first problem is defining how the file system should look to the user. This task involves defining
a file and its attributes, the operations allowed on a file, and the directory structure for organizing
files.
The second problem is creating algorithms and data structures to map the logical file system onto
the physical secondary-storage devices.
The file system itself is generally composed of many different levels.
The structure shown in Figure 12.1 is an example of a layered design. Each level in the design uses the
features of lower levels to create new features for use by higher levels.
121
Page
The I/O control: consists of device drivers and interrupt handlers to transfer information between the
main memory and the disk system.
The device driver usually writes specific bit patterns to special locations in the I/O controller’s memory to
tell the controller which device location to act on and what actions to take.
The basic file system needs only to issue generic commands to the appropriate device driver to read and
write physical blocks on the disk. Each physical block is identified by its numeric disk address (for example,
drive 1, cylinder 73, track 2, sector 10).
This layer also manages the memory buffers and caches that hold various file-system, directory, and data
blocks. A block in the buffer is allocated before the transfer of a disk block can occur.
The file-organization module knows about files and their logical blocks, as well as physical blocks. By
knowing the type of file allocation used and the location of the file, the file-organization module can
translate logical block addresses to physical block addresses for the basic file system to transfer. Each file’s
logical blocks are numbered from 0 to n. so, physical blocks containing the data usually do not match the
logical numbers. A translation is needed to locate each block.
The logical file system manages metadata information. Metadata includes all of the file-system structure
except the actual data (or contents of the files). The logical file system manages the directory structure to
provide the file-organization module with the information the latter needs, given a symbolic file name. It
maintains file structure via file-control blocks. A file control block (FCB) (an inode in UNIX file systems)
contains information about the file, including ownership, permissions, and location of the file contents.
Advantages:
When a layered structure is used for file-system implementation, duplication of code is minimized.
The I/O control and sometimes the basic file-system code can be used by multiple file systems.
Each file system can then have its own logical file-system and file-organization modules.
Disadvantages:
Layering can introduce more operating-system overhead, which may result in decreased
performance.
The use of layering, including the decision about how many layers to use and what each layer
should do, is a major challenge in designing new systems.
A Directory Structure (per file system) is used to organize the files. A PER-FILE FCB contains many details
about the file.
A file has been created; it can be used for I/O. First, it must be opened. The open( ) call passes a file name to
the logical file system. The open( ) system call First searches the system wide open file table to see if the
file is already in use by another process. If it is a per process open file table entry is created pointing to the
existing system wide open file table. If the file is not already open, the directory structure is searched for
the given file name. Once the file is found, FCB is copied into a system wide open file table in memory. This
table not only stores the FCB but also tracks the number of processes that have the file open.
Next, an entry is made in the per – process open file table, with the pointer to the entry in the system wide
open file table and some other fields. These are the fields include a pointer to the current location in the file
(for the next read/write operation) and the access mode in which the file is open.
The open () call returns a pointer to the appropriate entry in the per-process file system table. All file
operations are preformed via this pointer. When a process closes the file, the per- process table entry is
removed. And the system wide entry open count is decremented. When all users that have opened the file
close it, any updated metadata is copied back to the disk base directory structure. System wide open file
table entry is removed.
System wide open file table contains a copy of the FCB of each open file, other information. Per process
open file table, contains a pointer to the appropriate entry in the system wide open file table, other
information.
123
Page
1. Contiguous Allocation
In this scheme, each file occupies a contiguous set of blocks on the disk. For example, if a file
requires n blocks and is given a block b as the starting location, then the blocks assigned to the file
will be: b, b+1, b+2,……b+n-1.
This means that given the starting block address and the length of the file (in terms of blocks
required), we can determine the blocks occupied by the file.
The directory entry for a file with contiguous allocation contains
1. Address of starting block
2. Length of the allocated portion.
The file ‘mail’ in the following figure starts from the block 19 with length = 6 blocks. Therefore, it
occupies 19, 20, 21, 22, 23, 24 blocks.
Advantages:
Both the Sequential and Direct Accesses are supported by this. For direct access, the address of the
kth block of the file which starts at block b can easily be obtained as (b+k).
This is extremely fast since the number of seeks are minimal because of contiguous allocation of file
blocks.
124
Disadvantages:
This method suffers from both internal and external fragmentation. This makes it inefficient in
terms of memory utilization.
Page
2. Linked Allocation
In this scheme, each file is a linked list of disk blocks which need not be contiguous.
The disk blocks can be scattered anywhere on the disk.
The directory entry contains a pointer to the starting and the ending file block.
Each block contains a pointer to the next block occupied by the file.
The file ‘jeep’ in following image shows how the blocks are randomly distributed. The last block (25)
contains -1 indicating a null pointer and does not point to any other block.
Disadvantages:
1. It does sequential access efficiently and is not for direct access
2. Each block contains a pointer, wasting space
3. Blocks scatter everywhere and a large number of disk seeks may be necessary
4. Reliability: what if a pointer is lost or damaged?
3. Indexed Allocation
In this scheme, a special block known as the Index block contains the pointers to all the blocks
occupied by a file. Each file has its own index block.
The ith entry in the index block contains the disk address of the ith file block.
125
The directory entry contains the address of the index block as shown in the image:
Page
Advantages:
This supports direct access to the blocks occupied by the file and therefore provides fast access to
the file blocks.
It overcomes the problem of external fragmentation.
Disadvantages:
The pointer overhead for indexed allocation is greater than linked allocation.
For very small files, say files that expand only 2-3 blocks, the indexed allocation would keep one
entire block (index block) for the pointers which is inefficient in terms of memory utilization.
However, in linked allocation we lose the space of only 1 pointer per block.
File system maintains free-space list to track available blocks/clusters Linked list (free list)
A Bitmap or Bit Vector is series or collection of bits where each bit corresponds to a disk block. The bit can
take two values: 0 and 1: 0 indicates that the block is allocated and 1 indicates a free block.
The given instance of disk blocks on the disk in Figure 1 (where green blocks are allocated) can be
represented by a bitmap of 16 bits as: 0000111000000110.
126
Page
Advantages:
Simple to understand.
Finding the first free block is efficient. It requires scanning the words (a group of 8 bits) in a bitmap
for a non-zero word. (A 0-valued word has all bits 0). The first free block is then found by scanning
for the first 1 bit in the non-zero word.
Linked list
In this approach, the free disk blocks are linked together i.e. a free block contains a pointer to the next free
block. The block number of the very first disk block is stored at a separate location on disk and is also
cached in memory.
127
Page
Modify linked list to store address of next n-1 free blocks in first free block, plus a pointer to next block that
contains free-block-pointers (like this one).
An advantage of this approach is that the addresses of a group of free disk blocks can be found easily
Counting
Because space is frequently contiguously used and freed, with contiguous- allocation, extents, or clustering.
Keep address of first free block and count of following free blocks. Free space list then has entries
containing addresses and counts.
DIRECTORY IMPLEMENTATION
There is the number of algorithms by using which, the directories can be implemented. However, the
selection of an appropriate directory implementation algorithm may significantly affect the performance of
the system.
The directory implementation algorithms are classified according to the data structure they are
using. There are mainly two algorithms which are used in these days.
1. Linear List
In this algorithm, all the files in a directory are maintained as singly lined list. Each file contains the pointers
to the data blocks which are assigned to it and the next file in the directory.
Characteristics
1. When a new file is created, then the entire list is checked whether the new file name is matching to a
existing file name or not. In case, it doesn't exist, the file can be created at the beginning or at the end.
Therefore, searching for a unique name is a big concern because traversing the whole list takes time.
2. The list needs to be traversed in case of every operation (creation, deletion, updating, etc) on the files
therefore the systems become inefficient.
2. Hash Table
To overcome the drawbacks of singly linked list implementation of directories, there is an alternative
approach that is hash table. This approach suggests to use hash table along with the linked lists.
A key-value pair for each file in the directory gets generated and stored in the hash table. The key can be
determined by applying the hash function on the file name while the key points to the corresponding file
stored in the directory.
Now, searching becomes efficient due to the fact that now, entire list will not be searched on every operating.
Only hash table entries are checked using the key and if an entry found then the corresponding file will be
fetched using the value.
128
Page
These system calls are fundamental to how a program interacts with the operating system, particularly
for file and device I/O.
1. open():
Purpose: Establishes a connection between a process and a file or device. It returns a file
descriptor, which is a small, non-negative integer used to identify the opened file or device in
subsequent system calls.
Usage:
o Opening files for reading, writing, or both.
o Creating new files.
o Specifying file access modes (read-only, write-only, read-write).
o Setting file creation flags (e.g., create if not exists, truncate).
Example:
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
129
int main() {
int fd = open("myfile.txt", O_RDWR | O_CREAT, 0644); // Open for
read/write, create if needed, permissions 0644
Page
if (fd == -1) {
perror("open");
2. create():
Purpose: Creates a new file. It's largely superseded by open() with the O_CREAT flag.
Usage:
o Historically used to create new files.
o It is generally recommended to use open() instead.
Example:
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int fd = creat("newfile.txt", 0600); // Create a new file with
permissions 0600
if(fd == -1){
perror("create");
return 1;
}
close(fd);
return 0;
}
3. read():
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main() {
int fd = open("myfile.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
char buffer[1024];
ssize_t bytesRead = read(fd, buffer, sizeof(buffer));
if (bytesRead == -1) {
perror("read");
close(fd);
return 1;
}
130
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main() {
int fd = open("myfile.txt", O_WRONLY | O_APPEND | O_CREAT, 0644);
if (fd == -1) {
perror("open");
return 1;
}
const char *message = "Hello, world!\n";
ssize_t bytesWritten = write(fd, message, strlen(message));
if (bytesWritten == -1) {
perror("write");
close(fd);
return 1;
}
close(fd);
return 0;
}
5. close():
6. lseek():
Purpose: Changes the file offset (the position where the next read or write operation will occur).
Usage:
o Moving to specific positions within a file.
o Creating "holes" in files.
o Finding the size of a file.
Example:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main() {
131
return 1;
7. stat():
Purpose: Retrieves file or directory status information (e.g., size, permissions, modification
time).
Usage:
o Checking file existence.
o Determining file type (regular file, directory, etc.).
o Getting file size.
Example:
#include <sys/stat.h>
#include <stdio.h>
int main() {
struct stat fileStat;
if (stat("myfile.txt", &fileStat) == -1) {
perror("stat");
return 1;
}
printf("File size: %ld bytes\n", fileStat.st_size);
printf("File permissions: %o\n", fileStat.st_mode & 0777); // Extract
permission bits
return 0;
}
8. ioctl():
Purpose: Performs device-specific control operations. It's a very versatile system call used for a
wide range of tasks.
Usage:
o Configuring device settings (e.g., terminal settings, network interface parameters).
o Sending commands to devices.
o Retrieving device status.
Example:
o ioctl() is very device specific. For example, it is used to get the window size of a
terminal, or to configure network interfaces. Because of the device specific nature, it is
hard to give a general simple example.
132
Page