Operating System
Operating System
Operating System
Course code:22BCE4C2
Core Course-VI OPERATING SYSTEM
Unit -I
Unit-II
Processes: Process Concept - Process Scheduling - Operations on Processes -
Interprocess Communication - Process Synchronization : Background - The Critical- Section Problem
- Peterson’s Solution - Synchronization Hardware - Mutex Locks - Semaphores - Classic Problems of
Synchronization – Monitors.
Unit -III
CPU Scheduling : Basic Concepts - Scheduling Criteria - Scheduling Algorithms - Thread Scheduling -
Multiple-Processor Scheduling - Real-Time CPU Scheduling - Deadlocks: System Model - Deadlock
Characterization - Methods for Handling Deadlocks - Deadlock Prevention - Deadlock Avoidance -
Deadlock Detection - Recovery from Deadlock
Unit -IV
Main Memory : Background - Swapping - Contiguous Memory Allocation -
Segmentation - Paging - Structure of the Page Table - Virtual Memory: Background - Demand Paging
- Copy-on-Write - Page Replacement - Allocation of Frames - Thrashing - Memory-Mapped Files -
Allocating Kernel Memory
Unit -V
Mass-Storage Structure: Overview of Mass-Storage - Structure - Disk Structure - Disk Attachment -
Disk Scheduling - Disk Management - Swap-Space Management - RAID Structure - Stable-Storage
Implementation - File-System Implementation: File- System Structure - File-System Implementation
- Directory Implementation – Allocation Methods - Free-Space Management - Efficiency and
Performance – Recovery
Text Book:
"Operating System Concepts", Abraham Silberschatz, Peter Baer Galvin,Greg Gagne, Ninth Edition,
John Wiley & Sons, Inc
What is an Operating System?
A program that acts as an intermediary between a user of a computer and the computer
hardware
Operating system goals:
• Execute user programs and make solving user problems easier
• Make the computer system convenient to use
• Use the computer hardware in an efficient manner
Computer System Structure
Computer system can be divided into four components
• Hardware – provides basic computing resources
CPU, memory, I/O devices
• Operating system
Controls and coordinates use of hardware among various applications and users
• Application programs – define the ways in which the system resources are used to
solve the computing problems of the users
Word processors, compilers, web browsers, database systems, video games
• Users
People, machines, other computers
Four Components of a Computer System
Operating System Definition
• An operating system as a resource allocator. A computer system has many resources
that may be required to solve a problem: CPU time, memory space, file-storage space,
I/O devices, and so on. The operating system acts as the manager of these resources.
• Decides between conflicting requests for efficient and fair resource use
• OS is a control program A control program manages the execution of user programs
to prevent errors and improper use of the computer. It is especially concerned with the
operation and control of I/O devices.
• “OS is the one program running at all times on the computer” is the kernel. Everything
else is either a system program (ships with the operating system) or an application
program
• System programs which are associated with the operating system but are not part of
the kernel, and application programs which include all programs not associated with
the operation of the system.)
Computer Startup
• bootstrap program is loaded at power-up or reboot
• Typically stored in ROM or EPROM, generally known as firmware
• Initializes all aspects of system
• Loads operating system kernel and starts execution
• Once the kernel is loaded and executing, it can start providing services to the system and
its users. Some services are provided outside of the kernel, by system programs that are
loaded into memory at boot time to become system processes, or system daemons that
run the entire time the kernel is running. On UNIX, the first system process is “init,” and
it starts many other daemons. Once this phase is complete, the system is fully booted,
and the system waits for some event to occur.
Interrupt Handling
• The operating system preserves the state of the CPU by storing registers and the
program counter
• Determines which type of interrupt has occurred:
• Separate segments of code determine what action should be taken for each type of
interrupt
Interrupt Timeline
I/O Structure
• A general-purpose computer system consists of CPUs and multiple device controllers
that are connected through a common bus. Each device controller is in charge of a
specific type of device. Depending on the controller, more than one device may be
attached. For instance, seven or more devices can be attached to the small computer-
systems interface (SCSI) controller.
• A device controller maintains some local buffer storage and a set of special-purpose
registers. The device controller is responsible for moving the data between the
peripheral devices that it controls and its local buffer storage. Typically, operating
systems have a device driver for each device controller. This device driver understands
the device controller and provides the rest of the operating system with a uniform
interface to the device.
• To start an I/O operation, the device driver loads the appropriate registers within the
device controller. The device controller, in turn, examines the contents of these registers
to determine what action to take (such as “read a character from the keyboard”). The
controller starts the transfer of data from the device to its local buffer. Once the transfer
of data is complete, the device controller informs the device driver via an interrupt that
it has finished its operation. The device driver then returns control to the operating
system, possibly returning the data or a pointer to the data if the operation was a read.
For other operations, the device driver returns status information.
• System call – request to the operating system to allow user to wait for I/O completion
• Device-status table contains entry for each I/O device indicating its type, address, and
state
• Operating system indexes into I/O device table to determine device status and to modify
table entry to include interrupt
Storage Structure
The CPU can load instructions only from memory, so any programs to run must be stored there.
General-purpose computers run most of their programs from rewriteable memory, called main
memory (also called or RAM). Main commonly is implemented in a semiconductor technology
called DRAM.
All forms of memory provide an array of words. Each word has its own address. Interaction
is achieved through a sequence of load or store instructions to specific memory addresses. The
load instruction moves a word from main memory to an internal register within the CPU,
whereas the store instruction moves the content of a register to main memory.
Ideally, we want the programs and data to reside in main memory permanently. This
arrangement usually is not possible for the following two reasons:
1) Main memory is usually too small to store all needed programs and data permanently.
2) Main memory is a volatile storage device that loses its contents when power is turned
off or otherwise lost.
Thus, most computer systems provide secondary storage as an extension of main memory.
The main requirement for secondary storage is that it be able to hold large quantities of data
permanently. The most common secondary-storage device is a magnetic disk which provides
storage for both programs and data.
• Main memory – only large storage media that the CPU can access directly
• Secondary storage – extension of main memory that provides large nonvolatile storage
capacity
• Magnetic disks – rigid metal or glass platters covered with magnetic recording
material
Storage Hierarchy
• Storage systems organized in hierarchy
• Speed
• Cost
• Volatility
Caching – copying information into faster storage system; main memory can be viewed as a
last cache for secondary storage
Computer-System Architecture
• Most systems use a single general-purpose processor (PDAs through mainframes)
• Most systems have special-purpose processors as well
• Multiprocessors systems growing in use and importance
• Also known as parallel systems, tightly-coupled systems
Advantages include
1. Increased throughput
2.Economy of scale
3. Increased reliability – graceful degradation or fault tolerance
Two types
1. Asymmetric Multiprocessing
2.Symmetric Multiprocessing
How a Modern Computer Works
Symmetric Multiprocessing Architecture
Multiprocessing adds CPUs to increase computing power. If the CPU has an integrated memory
controller, then adding CPUs can also increase the amount of memory addressable in the
system. Either way, multiprocessing can cause a system to change its memory access model
from uniform memory access to non-uniform memory access UMA is defined as the situation
in which access to any RAM from any CPU takes the same amount of time. With NUMA, some
parts of memory may take longer to access than other parts, creating a performance penalty.
Operating systems can minimize the NUMA penalty through resource management.
A Dual-Core Design
We show a dual-core design with two cores on the samechip. In this design, each core has its
own register set as well as its own localcache; other designs might use a shared cache or a
combination of local andshared caches.
Blade servers are a recent development in which multiple processor boards, I/0 boards, and
networking boards are placed in the same chassis. The difference between these and traditional
multiprocessor systems is that each blade-processor board boots independently and runs its
own operating system.
Clustered Systems
Another type of multiprocessor system is a clustered system, which gathers together multiple
CPUs. Clustered systems differ from the multiprocessor systems (loosely coupled). Clustering
is usually used to provide high-availability service — that is, service will continue even if one
or more systems in the cluster fail.
However, applications must be written to take advantage of the cluster by using a technique
known as parallelization which consists of dividing a program into separate components that
run in parallel on individual computers in the cluster.
Because most operating systems lack support for simultaneous data access by multiple
hosts, parallel clusters are usually accomplished by use of special versions of software and
special releases of applications. For example, Oracle Real Application Cluster is a version of
Oracle's database that has been designed to run on a parallel cluster. Each machine runs Oracle,
and a layer of software tracks access to the shared disk. Each machine has full access to all data
in the database. To provide this shared access to data, the system must also supply access
control and locking to ensure that no conflicting operations occur. This function, commonly
known as a is distributed lock manager (DLM).
Time sharing and multiprogramming require that several jobs be kept simultaneously
in memory. If several jobs are ready to be brought into memory,and if there is not enough room
for all of them, then the system must choose among them. Making this decision involves job
scheduling.
If several jobs are ready to run at the same time, the system must choose which job will
run first. Making this decision is CPU scheduling. In a time-sharing system, the operating
system must ensure reasonable response time. This goal is sometimes accomplished through
swapping, whereby processes are swapped in and out of main memory to the disk.
A more common method for ensuring reasonable response time is virtual memory, a
technique that allows the execution of a process that is not completely in memory. The main
advantage of the virtual-memory scheme is that it enables users to run programs that are larger
than actual physical memory
Operating-System Operations
Modern operating systems are interrupt driven. If there are no processes to execute, no I/O
devices to service, and no users to whom to respond, an operating system will sit quietly,
waiting for something to happen. Events are almost always signaled by the occurrence of an
interrupt or a trap. A trap (or an exception) is a software-generated interrupt caused either
by an error (for example, division by zero or invalid memory access) or by a specific request
from a user program that an operating-system service be performed. For each type of interrupt,
separate segments of code in the operating system determine what action should be taken. An
interrupt service routine is provided to deal with the interrupt.
At system boot time, the hardware starts in kernel mode. The operating system is then
loaded and starts user applications in user mode. Whenever a trap or interrupt occurs, the
hardware switches from user mode to kernel mode (that is, changes the state of the mode bit
to 0). Thus, whenever the operating system gains control of the computer, it is in kernel mode.
The system always switches to user mode (by setting the mode bit to 1) before passing control
to a user program.
System calls provide the means for a user program to ask the operating system to
perform tasks reserved for the operating system on the user program’s behalf. A system call
is invoked in a variety of ways, depending on the functionality provided by the underlying
processor. In all forms, it is the method used by a process to request action by the operating
system. A system call usually takes the form of a trap to a specific location in the interrupt
vector. This trap can be executed by a generic trap instruction, although some systems (such as
MIPS) have a specific syscall instruction to invoke a system call.
Timer
We must ensure that the operating system maintains control over the CPU. We cannot allow a
user program to get stuck in an infinite loop or to fail to call system services and never return
control to the operating system. To accomplish this goal, we can use a timer. A timer can be set
to interrupt the computer after a specified period. The period may be fixed (for example, 1/60
second) or variable (for example, from 1 millisecond to 1 second). A variable timer is generally
implemented by a fixed-rate clock and a counter. The operating system sets the counter. Every
time the clock ticks, the counter is decremented. When the counter reaches 0,
an interrupt occurs. For instance, a 10-bit counter with a 1-millisecond clock allows interrupts
at intervals from 1 millisecond to 1,024 milliseconds, in steps of 1 millisecond. We can use the
timer to prevent a user program from running too long.
Process Management
A program does nothing unless its instructions are executed by a CPU. A program in execution,
as mentioned, is a process. A time-shared user program such as a compiler is a process. A word-
processing program being run by an individual user on a PC is a process. A system task, such as
sending output to a printer, can also be a process (or at least part of one).
A process needs certain resources—including CPU time, memory, files, and I/O
devices—to accomplish its task. These resources are either given to the process when it is
created or allocated to it while it is running. In addition to the various physical and logical
resources that a process obtains when it is created, various initialization data (input) may be
passed along.
A single-threaded process has one program counter specifying the next instruction to
execute. The execution of such a process must be sequential. The CPU executes one instruction
of the process after another, until the process completes. A multithreaded process has multiple
program counters, each pointing to the next instruction to execute for a given thread.
The operating system is responsible for the following activities in connection with process
management:
Process Management Activities
• Scheduling processes and threads on the CPUs
• Creating and deleting both user and system processes
• Suspending and resuming processes
• Providing mechanisms for process synchronization
• Providing mechanisms for process communication
• A process is a program in execution. It is a unit of work within the system. Program is a
passive entity, process is an active entity.
• Process needs resources to accomplish its task
• Process termination requires reclaim of any reusable resources
• Single-threaded process has one program counter specifying location of next
instruction to execute
• Process executes instructions sequentially, one at a time, until completion
• Multi-threaded process has one program counter per thread
• Typically system has many processes, some user, some operating system running
concurrently on one or more CPUs
Memory Management
The main memory is central to the operation of a modern computer system. Main memory is
a large array of bytes, ranging in size from hundreds of thousands to billions. Each byte has its
own address. Main memory is a repository of quickly accessible data shared by the CPU and I/O
devices. The central processor reads instructions from main memory during the instruction-
fetch cycle and both reads and writes data from main memory during the data- fetch cycle.
For a program to be executed, it must be mapped to absolute addresses and loaded into
memory. As the program executes, it accesses program instructions and data from memory by
generating these absolute addresses. Eventually, the program terminates, its memory space is
declared available, and the next program can be loaded and executed.
To improve both the utilization of the CPU and the speed of the computer’s response to its
users, general-purpose computers must keep several programs in memory, creating a need for
memory management.
File-System Management
File management is one of the most visible components of an operating system. Computers can
store information on several different types of physical media. Magnetic disk, optical disk, and
magnetic tape are the most common. Each of these media has its own characteristics and
physical organization. Each medium is controlled by a device, such as a disk drive or tape drive,
that also has its own unique characteristics. These properties include access speed, capacity,
data-transfer rate, and access method (sequential or random).
Mass-Storage Management
The operating system is responsible for the following activities in connection with disk
management:
• Free-space management
• Storage allocation
• Disk scheduling
Magnetic tape drives and their tapes and CD and DVD drives and platters are typical tertiary
storage devices.
Caching
When we need a particular piece of information, we first check whether it is in the cache. If it
is, we use the information directly from the cache. If it is not, we use the information from the
source, putting a copy in the cache under the assumption that we will need it again soon.
Other caches are implemented totally in hardware. For instance, most systems have an
instruction cache to hold the instructions expected to be executed next. Without this cache,
the CPU would have to wait several cycles while an instruction was fetched from main
memory.Because caches have limited size, cache management is an important design problem.
Careful selection of the cache size and of a replacement policy can result in greatly increased
performance.
Main memory can be viewed as a fast cache for secondary storage, since data in
secondary storage must be copied into main memory for use and data must be in main memory
before being moved to secondary storage for safekeeping. The file-system data,which resides
permanently on secondary storage, may appear on several levels in the storage hierarchy. At
the highest level, the operating system may maintain a cache of file-system data in main
memory.
I/O Subsystem
The I/O subsystem consists of several components:
• A memory-management component that includes buffering, caching, and spooling
• A general device-driver interface
• Drivers for specific hardware devices
Protection and security require the system to be able to distinguish among all its users.
Most operating systems maintain a list of user names and associated user identifiers (user IDs).
In Windows parlance, this is a security ID (SID). These numerical IDs are unique, one peruser.
When a user logs in to the system, the authentication stage determines the appropriate user ID
for the user. That user ID is associated with all of the user’s processes and threads. When an ID
needs to be readable by a user, it is translated back to the user name via the user name list.
In some circumstances, we wish to distinguish among sets of users rather than individual users.
For example, the owner of a file on a UNIX system may be allowed to issue all operations on
that file, whereas a selected set of users may be allowed only to read the file. Toaccomplish this,
we need to define a group name and the set of users belonging to that group. Group
functionality can be implemented as a system-wide list of group names and group identifiers.
A user can be in one or more groups, depending on operating-system design decisions. The
user’s group IDs are also included in every associated process and thread.
• Systems generally first distinguish among users, to determine who can do what
• User identities (user IDs, security IDs) include name and associated number, one per
user
• User ID then associated with all files, processes of that user to determine access
control
• Group identifier (group ID) allows set of users to be defined and controls managed,
then also associated with each process, file
• Privilege escalation allows user to change to effective ID with more rights
Operating-System Services
An operating system provides an environment for the execution of programs. It provides
certain services to programs and to the users of those programs. The specific services provided,
of course, differ from one operating system to another, but we can identify common classes.
User interface. Almost all operating systems have a user interface (UI). This interface can
take several forms. One is a command-line interface (CLI), which uses text commands and a
method for entering them (say, a keyboard for typing in commands in a specific format with
specific options). Another is a batch interface, in which commands and directives to control
those commands are entered into files, and those files are executed. Most commonly, a
graphical user interface (GUI) is used. Here, the interface is a window system with a pointing
device to direct I/O, choose from menus, and make selections and a keyboard toenter text.
• Program execution. The system must be able to load a program into memory and to run
that program. The program must be able to end its execution, either normally or abnormally
(indicating error).
• I/O operations. A running program may require I/O, which may involve a file or an I/O
device. For specific devices, special functions may be desired (such as recording to a CD or
DVD drive or blanking a display screen). For efficiency and protection, users usually cannot
control I/O devices directly. Therefore, the operating system must provide a means to do
I/O.
• File-system manipulation. The file system is of particular interest. Obviously, programs
need to read and write files and directories. They also need to create and delete them by
name, search for a given file, and list file information. Finally, some operating systems
include permissions management to allow or deny access to files or directories based on
file ownership.
• Communications. There are many circumstances in which one process needs to exchange
information with another process. Such communication may occur between processes that
are executing on the same computer or between processes that are executing on different
computer systems tied together by a computer network. Communications may be
implemented via shared memory, in which two or more processes read and write to a
shared section of memory, or message passing, in which packets of information in
predefined formats are moved between processes by the operating system.
• Error detection. The operating system needs to be detecting and correcting errors
constantly. Errors may occur in the CPU and memory hardware (such as a memory error or
a power failure), in I/O devices (such as a parity error on disk, a connection failure on a
network, or lack of paper in the printer), and in the user program (such as an arithmetic
overflow, an attempt to access an illegal memory location, or a too-great use of CPU time).
For each type of error, the operating system should take the appropriate action to ensure
correct and consistent computing.
• Resource allocation. When there are multiple users or multiple jobs running at the same
time, resources must be allocated to each of them. The operating system manages many
different types of resources. Some (such as CPU cycles, main memory, and file storage) may
have special allocation code, whereas others (such as I/O devices) may have much more
general request and release code. For instance, in determining how best to use the CPU,
operating systems have CPU-scheduling routines that take into account the speed of the
CPU, the jobs that must be executed, the number of registers available, and other factors.
• Accounting. We want to keep track of which users use how much and what kinds of
computer resources. This record keeping may be used for accounting (so that users can be
billed) or simply for accumulating usage statistics. Usage statistics may be a valuable tool
for researchers who wish to reconfigure the system to improve computing services.
• Protection and security. The owners of information stored in a multiuser or networked
computer system may want to control use of that information. When several separate
processes execute concurrently, it should not be possible for one process to interfere with
the others or with the operating system itself. Protection involves ensuring that all access
to system resources is controlled.
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-leveltasks
(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.
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.
To start a new process, the shell executes a fork() system call. Then, the selected program is
loaded into memory via an exec() system call, and the program is executed. Depending on the
way the command was issued, the shell then either waits for the process to finish or runs the
process “in the background.”
File Management
We first need to be able to create() and delete() files. Either system call requires the name of
the file and perhaps some of the file’s attributes. Once the file is created, we need to open() it
and to use it. We may also read(), write(), or reposition() (rewind or skip to the end of the file,
for example). Finally, we need to close() the file, indicating that we are no longer using it.
Device Management
Process may need several resources to execute—main memory, disk drives, access to files, and
so on. If the resources are available, they can be granted, and control can be returned to the
user process. Otherwise, the process will have to wait until sufficient resources are available.
The various resources controlled by the operating system can be thought of as devices. Some
of these devices are physical devices (for example, disk drives), while others
can be thought of as abstract or virtual devices (for example, files).A system with multiple users
may require us to first request() a device, to ensure exclusive use of it. After we are finished
with the device, we release() it. Once the device has been requested (and allocated to us), we
can read(), write(), and (possibly) reposition() the device, just as we can with files.
Information Maintenance
Many system calls exist simply for the purpose of transferring information between the user
program and the operating system. For example, most systems have a system call to return the
current time() and date(). Other system calls may return information about the system, such as
the number of current users, the version number of the operating system, the amount of free
memory or disk space, and so on. Another set of system calls is helpful in debugging a program.
Many systems provide system calls to dump() memory. This provision is useful for debugging.
Communication
There are two common models of inter process communication: the message passing model
and the shared-memory model. In the message-passing model, the communicating processes
exchange messages with one another to transfer information. Messages can be exchanged
between the processes either directly or indirectly through a common mailbox. Before
communication can take place, a connection must be opened.
In the shared-memory model, processes use shared memory create() and shared memory
attach() system calls to create and gain access to regions of memory owned by other processes.
Protection
Protection provides a mechanism for controlling access to the resources provided by a
computer system. Typically, system calls providing protection include set permission() and get
permission(), which manipulate the permission settings of resources such as files and disks.
The allow user() and deny user() system calls specify whether particular users can—or
cannot—be allowed access to certain resources.
System Programs
System programs, also known as system utilities, provide a convenient environment for
program development and execution. Some of them are simply user interfaces to system calls.
Others are considerably more complex. They can be divided into these categories:
• File management: These programs create, delete, copy, rename, print, dump, list, and
generally manipulate files and directories.
• Status information: Some programs simply ask the system for the date, time, amount
of available memory or disk space, number of users, or similar status information.
Others are more complex, providing detailed performance, logging, and debugging
information.
• File modification: Several text editors may be available to create and modify the
content of files stored on disk or other storage devices. There may also be special
commands to search contents of files or perform transformations of the text.
• Programming-language support: Compilers, assemblers, debuggers, and interpreters
for common programming languages (such as C, C++, Java, and PERL) are often provided
with the operating system or available as a separate download.
• Program loading and execution: Once a program is assembled or compiled, it must be
loaded into memory to be executed. The system may provide absolute loaders,
relocatable loaders, linkage editors, and overlay loaders. Debugging systems for either
higher-level languages or machine language are needed as well.
• Background services: All general-purpose systems have methods for launching certain
system-program processes at boot time. Some of these processes terminate after
completing their tasks, while others continue to run until the system is halted.
Constantly running system-program processes are known as services, subsystems, or
daemons.
Along with system programs, most operating systems are supplied with programs that are
useful in solving common problems or performing common operations. Such application
programs include Web browsers, word processors and text formatters, spreadsheets, database
systems, compilers, plotting and statistical-analysis packages, and games.
UNIT-2 NOTES
Process:
A process, which is a program in execution. A process is the unit of work in a modern
time-sharing system. A system therefore consists of a collection of processes: operating system
processes executing system code and user processes executing user code. Potentially, all these
processes can execute concurrently, with the CPU (or CPUs) multiplexed among them. By
switching the CPU between processes, the operating system can make the computer more
productive.
A process is also known as job or task. A process is more than the program code, which
is sometimes known as the text section. It also includes the current activity, as represented by
the value of the program counter and the contents of the processor’s registers. A process
generally also includes the process stack, which contains temporary data (such as function
parameters, return addresses, and local variables), and a data section, which contains global
variables. A process may also include a heap, which is memory that is dynamically allocated
during process run time. The structure of a process in memory is shown in Figure 3.1.
We emphasize that a program by itself is not a process. A program is a passive entity, such as
a file containing a list of instructions stored on disk (often called an executable file). In
contrast, a process is an active entity, with a program counter specifying the next instruction
to execute and a set of associated resources. A program becomes a process when an executable
file is loaded into memory.
Process State
As a process executes, it changes state. The state of a process is defined in part by the current
activity of that process. A process may be in one of the following states:
• New. The process is being created.
• Running. Instructions are being executed.
• Waiting. The process is waiting for some event to occur (such as an I/O
completion or reception of a signal).
• Ready. The process is waiting to be assigned to a processor.
• Terminated. The process has finished execution.
It is important to realize that only one process can be running on any processor at any instant.
Many processes may be ready and waiting, however. The state diagram corresponding to these
states is presented in Figure 3.2.
Process state. The state may be new, ready, running, and waiting, halted, and so on.
• Program counter. The counter indicates the address of the next instruction to be executed
for this process.
• CPU registers. The registers vary in number and type, depending on the computer
architecture. They include accumulators, index registers, stack pointers, and general-purpose
registers, plus any condition-code information. Along with the program counter, this state
information must be saved when an interrupt occurs, to allow the process to be continued
correctly afterward (Figure 3.4).
• CPU-scheduling information. This information includes a process priority, pointers to
scheduling queues, and any other scheduling parameters.
• Memory-management information. This information may include such items as the value
of the base and limit registers and the page tables, or the segment tables, depending on the
memory system used by the operating system.
• Accounting information. This information includes the amount of CPU and real time used,
time limits, account numbers, job or process numbers, and so on.
• I/O status information. This information includes the list of I/O devices allocated to the
process, a list of open files, and so on.
In brief, the PCB simply serves as the repository for any information that may vary from process
to process.
Threads
The process model discussed so far has implied that a process is a program that performs a
single thread of execution. For example, when a process is running a word-processor program,
a single thread of instructions is being executed. This single thread of control allows the process
to perform only one task at a time. The user cannot simultaneously type incharacters and run
the spell checker within the same process, for example. Most modern operating systems have
extended the process concept to allow a process to have multiple threads of execution and thus
to perform more than one task at a time. This feature is especially beneficial on multicore
systems, where multiple threads can run in parallel.
Operations on Processes
The processes in most systems can execute concurrently, and they may be created and deleted
dynamically.
Process Creation
During the course of execution, a process may create several new processes. As mentioned
earlier, the creating process is called a parent process, and the new processes are called the
children of that process. Each of these new processes may in turn create other processes,
forming a tree of processes. Most operating systems (including UNIX, Linux, and Windows)
identify processes according to a unique process identifier (or pid), which is typically an
integer number. The pid provides a unique value for each process in the system, and it can be
used as an index to access various attributes of a process within the kernel.
When a process creates a new process, two possibilities for execution exist:
1. The parent continues to execute concurrently with its children.
2. The parent waits until some or all of its children have terminated.
Process Termination
A process terminates when it finishes executing its final statement and asks the operating
system to delete it by using the exit() system call. At that point, the process may return a status
value (typically an integer) to its parent process (via the wait() system call). All the
resources of the process—including physical and virtual memory, open files, and I/O buffers—
are deallocated by the operating system.
A parent may terminate the execution of one of its children for a variety of reasons, such
as these:
• The child has exceeded its usage of some of the resources that it has been allocated. (To
determine whether this has occurred, the parent must have a mechanism to inspect the state
of its children.)
• The task assigned to the child is no longer required.
• The parent is exiting, and the operating system does not allow a child to continue if its parent
terminates.
Some systems do not allow a child to exist if its parent has terminated. In such systems, if a
process terminates (either normally or abnormally), then all its children must also be
terminated. This phenomenon, referred to as cascading termination, is normally initiated by
the operating system. A process that has terminated, but whose parent has not yet called wait(),
is known as a zombie process. All processes transition to this state when they terminate, but
generally they exist as zombies only briefly.
• Convenience. Even an individual user may work on many tasks at the same time. For
instance, a user may be editing, listening to music, and compiling in parallel.
Two types of buffers can be used. The unbounded buffer places no practical limit on
the size of the buffer. The consumer may have to wait for new items, but the producer can
always produce new items. The bounded buffer assumes a fixed buffer size. In this case, the
consumer must wait if the buffer is empty, and the producer must wait if the buffer is full.
computers connected by a network. For example, an Internet chat program could be designed
so that chat participants communicate with one another by exchanging messages. A message-
passing facility provides at least two operations:
send(message) receive(message)
Messages sent by a process can be either fixed or variable in size. Message passing may be
either blocking or nonblocking— also known as synchronous and asynchronous.
• Blocking send. The sending process is blocked until the message is received by the
receiving process or by the mailbox.
• Nonblocking send. The sending process sends the message and resumes operation.
• Blocking receive. The receiver blocks until a message is available.
• Nonblocking receive. The receiver retrieves either a valid message or a null.
Process Scheduling
The objective of multiprogramming is to have some process running at all times, to maximize
CPU utilization. The objective of time sharing is to switch the CPU among processes so
frequently that users can interact with each program while it is running. To meet these
objectives, the process scheduler selects an available process (possibly from a set of several
available processes) for program execution on the CPU. For a single-processor system, there
will never be more than one running process. If there are more processes, the rest will have to
wait until the CPU is free and can be rescheduled.
Scheduling Queues
As processes enter the system, they are put into a job queue, which consists of all processes
in the system. The processes that are residing in main memory and are ready and waiting to
execute are kept on a list called the ready queue. This queue is generally stored as a linked list.
A ready-queue header contains pointers to the first and final PCBs in the list. Each PCB includes
a pointer field that points to the next PCB in the ready queue. The list of processes waiting for
a particular I/O device is called a device queue.
A new process is initially put in the ready queue. It waits there until it is selected for
execution, or dispatched. Once the process is allocated the CPU and is executing, one of several
events could occur:
• The process could issue an I/O request and then be placed in an I/O queue.
• The process could create a new child process and wait for the child’s termination.
• The process could be removed forcibly from the CPU, as a result of an interrupt, and be put
back in the ready queue.
Schedulers
A process migrates among the various scheduling queues throughout its lifetime. The operating
system must select, for scheduling purposes, processes from these queues in some fashion. The
selection process is carried out by the appropriate scheduler.
Often, in a batch system, more processes are submitted than can be executed
immediately. These processes are spooled to a mass-storage device (typically a disk), where
they are kept for later execution. The long-term scheduler, or job scheduler, selects
processes from this pool and loads them into memory for execution. The short-term
scheduler, or CPU scheduler, selects from among the processes that are ready to execute and
allocates the CPU to one of them. The long-term scheduler executes much less frequently;
minutes may separate the creation of one new process and the next. The long-term scheduler
controls the degree of multiprogramming (the number of processes in memory).
It is important that the long-term scheduler make a careful selection. In general, most
processes can be described as either I/O bound or CPU bound. An I/O-bound process is one
that spends more of its time doing I/O than it spends doing computations. A CPU-bound
process, in contrast, generates I/O requests infrequently, using more of its time doing
computations. It is important that the long-term scheduler select a good process mix of I/O-
bound and CPU-bound processes. The system with the best performance will thus have a
combination of CPU-bound and I/O-bound processes.
Context Switch
Interrupts cause the operating system to change a CPU from its current task and to run a kernel
routine. Such operations happen frequently on general-purpose systems. When an interrupt
occurs, the system needs to save the current context of the process running on the CPU so that
it can restore that context when its processing is done, essentially suspending the process and
then resuming it.
Switching the CPU to another process requires performing a state save of the current
process and a state restore of a different process. This task is known as a context switch. When
a context switch occurs, the kernel saves the context of the old process in its PCB and loads the
saved context of the new process scheduled to run. Context-switch times are highly dependent
on hardware support.
Process synchronization
A situation where several processes access and manipulate the same data concurrently and the
outcome of the execution depends on the particular order in which the access takes place, is
called a race condition. To guard against the race condition we need to ensure that only one
process at a time can be manipulating the variable counter. To make such a guarantee, we
require that the processes be synchronized in some way.
The section of code implementing this request is the entry section. The critical section
may be followed by an exit section. The remaining code is the remainder section. The general
structure of a typical process Pi is shown in Figure 5.1. The entry section and exit section are
enclosed in boxes to highlight these important segments of code.
A solution to the critical-section problem must satisfy the following three requirements:
1. Mutual exclusion. If process Pi is executing in its critical section, then no other processes
can be executing in their critical sections.
2. Progress. If no process is executing in its critical section and some processes wish to enter
their critical sections, then only those processes that are not executing in their remainder
sections can participate in deciding which will enter its critical section next, and this selection
cannot be postponed indefinitely.
3. Bounded waiting. There exists a bound, or limit, on the number of times that other
processes are allowed to enter their critical sections after a process has made a request to enter
its critical section and before that request is granted.
Two general approaches are used to handle critical sections in operating systems:
1) Preemptive kernels and
2) non-Preemptive kernels.
A preemptive (preemption is the act of temporarily interrupting a task being carried
out by a computer system) kernel allows a process to be preempted while it is running in
kernel mode. A nonpreemptive kernel does not allow a process running in kernel mode to
preempted; a kernel-mode process will run until it exits kernel mode, blocks, or voluntarily
yields control of the CPU.
Peterson’s Solution
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.
Synchronization Hardware
Mutex Locks
operating-systems designers build software tools to solve the critical-section problem. The
simplest of these tools is the mutex lock. (In fact, the term mutex is short for mutual exclusion.)
We use the mutex lock to protect critical regions and thus prevent race conditions.That is, a
process must acquire the lock before entering a critical section; it releases the lock when it exits
the critical section. The acquire()function acquires the lock, and the release() function releases
the lock.
A mutex lock has a boolean variable available whose value indicates if the lock is
available or not. If the lock is available, a call to acquire() succeeds, and the lock is then
considered unavailable. A process that attempts to acquire an unavailable lock is blocked
until the lock is released.
The main disadvantage of the implementation given here is that it requires busy waiting. While
a process is in its critical section, any other process that tries to enter its critical section must
loop continuously in the call to acquire(). In fact, this type of mutex lock is also called a spinlock
because the process “spins” while waiting for the lock to become available.
Semaphores
Mutex locks, as we mentioned earlier, are generally considered the simplest of synchronization
tools. In this section, we examine a more robust tool that can behave similarly to a mutex lock
but can also provide more sophisticated ways for processes to synchronize their activities.
A semaphore S is an integer variable that, apart from initialization, is accessed only
through two standard atomic operations: wait() and signal(). The wait() operation was
originally termed P; signal() was originally called V . The definition of wait() is as follows:
wait(S) {
while (S <= 0)
; // busy wait
S--;
}
The definition of signal() is as follows:
signal(S) {
S++;
}
All modifications to the integer value of the semaphore in the wait() and signal() operations
must be executed indivisibly. That is, when one process modifies the semaphore value, no other
process can simultaneously modify that same semaphore value. In addition, in the case of
wait(S), the testing of the integer value of S (S ≤ 0), as well as its possible modification (S--),
must be executed without interruption.
Semaphore Usage
Operating systems often distinguish between counting and binary semaphores. The value of a
counting semaphore can range over an unrestricted domain. The value of a binary
semaphore can range only between 0 and 1. Thus, binary semaphores behave similarly to
mutex locks. In fact, on systems that do not provide mutex locks, binary semaphores can be
used instead for providing mutual exclusion.
We can also use semaphores to solve various synchronization problems. For example,
consider two concurrently running processes: P1 with a statement S1 and P2 with a statement
S2. Suppose we require that S2 be executed only after S1 has completed. We can implement this
scheme readily by letting P1 and P2 share a common semaphore synch, initialized to 0. In
process P1, we insert the statements
S1;
signal(synch);
In process P2, we insert the statements
wait(synch);
S2;
Because synch is initialized to 0, P2 will execute S2 only after P1 has invoked signal(synch),
which is after statement S1 has been executed.
Suppose that P0 executes wait(S) and then P1 executes wait(Q).When P0 executes wait(Q), it
must wait until P1 executes signal(Q). Similarly, when P1 executes wait(S), it must wait until
P0 executes signal(S). Since these signal() operations cannot be executed, P0 and P1 are
deadlocked. We say that a set of processes is in a deadlocked state when every process in the
set is waiting for an event that can be caused only by another process in the set.
Priority Inversion
A scheduling challenge arises when a higher-priority process needs to read or modify kernel
data that are currently being accessed by a lower-priority process—or a chain of lower- priority
processes. Since kernel data are typically protected with a lock, the higher-priority
process will have to wait for a lower-priority one to finish with the resource. The situation
becomes more complicated if the lower-priority process is preempted in favor of another
process with a higher priority.
Bounded buffer problem, which is also called producer consumer problem, is one of the
classic problems of synchronization. Let's start by understanding the problem here, before
moving on to the solution and program code.
There is a buffer of n slots and each slot is capable of storing one unit of data. There are two
processes running, namely, producer and consumer, which are operating on the buffer.
A producer tries to insert data into an empty slot of the buffer. A consumer tries to remove data
from a filled slot in the buffer. As you might have guessed by now, those two processes won't
produce the expected output if they are being executed concurrently.
There needs to be a way to make the producer and consumer work in an independent
manner.
Here's a Solution
One solution of this problem is to use semaphores. The semaphores which will be used here
are:
At any instant, the current value of empty represents the number of empty slots in the buffer
and full represents the number of occupied slots in the buffer.
do
wait(empty);
// acquire lock
wait(mutex);
// release lock
signal(mutex);
// increment 'full'
signal(full);
while(TRUE);
• it decrements the empty semaphore because, there will now be one less empty slot, since
the producer is going to insert data in one of those slots.
• Then, it acquires lock on the buffer, so that the consumer cannot access the buffer until
producer completes its operation.
• After performing the insert operation, the lock is released and the value of full is
incremented because the producer has just filled a slot in the buffer.
do
wait(full);
wait(mutex);
signal(mutex);
// increment 'empty'
signal(empty);
while(TRUE);
• The consumer waits until there is at least one full slot in the buffer.
• Then it decrements the full semaphore because the number of occupied slots will be
decreased by one, after the consumer completes its operation.
• After that, the consumer acquires lock on the buffer.
• Following that, the consumer completes the removal operation so that the data from one
of the full slots is removed.
• Then, the consumer releases the lock.
• Finally, the empty semaphore is incremented by 1, because the consumer has just
removed data from an occupied slot, thus making it empty.
Readers writer problem is another example of a classic synchronization problem. There are
many variants of this problem, one of which is examined below.
There is a shared resource which should be accessed by multiple processes. There are two
types of processes in this context. They are reader and writer. Any number of readers can
read from the shared resource simultaneously, but only one writer can write to the shared
resource. When a writeris writing data to the resource, no other process can access the
resource. A writer cannot write to the resource if there are non-zero number of readers
accessing the resource at that time.
The Solution
From the above problem statement, it is evident that readers have higher priority than writer.
If a writer wants to write to the resource, it must wait until there are no readers currently
accessing that resource.
Here, we use one mutex m and a semaphore w. An integer variable read_count is used to
maintain the number of readers currently accessing the resource. The variable read_count is
initialized to 0. A value of 1 is given initially to m and w.
Instead of having the process to acquire lock on the shared resource, we use the mutex m to
make the process to acquire and release lock whenever it is updating the read_count variable.
while(TRUE)
wait(w);
signal(w);
}
And, the code for the reader process looks like this:
while(TRUE)
//acquire lock
wait(m);
read_count++;
if(read_count == 1)
wait(w);
//release lock
signal(m);
/* perform the reading operation */
// acquire lock
wait(m);
read_count--;
if(read_count == 0)
signal(w);
// release lock
signal(m);
}
• As seen above in the code for the writer, the writer just waits on the w semaphore until it
gets a chance to write to the resource.
• After performing the write operation, it increments w so that the next writer can access
the resource.
• On the other hand, in the code for the reader, the lock is acquired whenever
the read_count is updated by a process.
• When a reader wants to access the resource, first it increments the read_count value,
then accesses the resource and then decrements the read_count value.
• The semaphore w is used by the first reader which enters the critical section and the last
reader which exits the critical section.
• The reason for this is, when the first readers enters the critical section, the writer is
blocked from the resource. Only new readers can access the resource now.
• Similarly, when the last reader exits the critical section, it signals the writer using the
w semaphore because there are zero readers now and a writer can have the chance to
access the resource.
The dining philosophers problem is another classic synchronization problem which is used to
evaluate situations where there is a need of allocating multiple resources to multiple processes.
Consider there are five philosophers sitting around a circular dining table. The dining table has
five chopsticks and a bowl of rice in the middle as shown in the below figure.
At any instant, a philosopher is either eating or thinking. When a philosopher wants to eat, he
uses two chopsticks - one from their left and one from their right. When a philosopher wants
to think, he keeps down both chopsticks at their original place.
From the problem statement, it is clear that a philosopher can think for an indefinite amount
of time. But when a philosopher starts eating, he has to stop at some point of time. The
philosopher is in an endless cycle of thinking and eating.
while(TRUE)
wait(stick[i]);
/*
wait(stick[(i+1) % 5]);
/* eat */
signal(stick[i]);
signal(stick[(i+1) % 5]);
/* think */
}
When a philosopher wants to eat the rice, he will wait for the chopstick at his left and picks up
that chopstick. Then he waits for the right chopstick to be available, and then picks it too. After
eating, he puts both the chopsticks down.
But if all five philosophers are hungry simultaneously, and each of them pickup one chopstick,
then a deadlock situation occurs because they will be waiting for another chopstick forever.
The possible solutions for this are:
• A philosopher must be allowed to pick up the chopsticks only if both the left and right
chopsticks are available.
• Allow only four philosophers to sit at the table. That way, if all the four philosophers pick
up four chopsticks, there will be one chopstick left on the table. So, one philosopher can
start eating and eventually, two chopsticks will be available. In this way, deadlocks can be
avoided.
Syntax of Monitor
Condition Variables
Two different operations are performed on the condition variables of the monitor.
1. Wait.
2. signal.
// Ignore signal
else
There exist some algorithm to solve Dining – Philosopher Problem, but they may have deadlock
situation. Also, a deadlock-free solution is not necessarily starvation-free. Semaphores can
result in deadlock due to programming errors. Monitors alone are not sufficiency to solve this,
we need monitors with condition variables
To code this solution, we need to distinguish among three states in which we may find a
philosopher. For this purpose, we introduce the following data structure:
monitor DP
status state[5];
condition self[5];
// Pickup chopsticks
Pickup(int i)
{
state[i] = hungry;
test(i);
if (state[i] != eating)
self[i].wait;
Putdown(int i)
{
state[i] = thinking;
// signaling R’s CV
test((i + 1) % 5);
test((i + 4) % 5);
test(int i)
if (state[(i + 1) % 5] != eating
state[i] = eating;
self[i].signal();
init()
{
for
i = 0 to 4
}
K. YUGASENTHILRAJA M.C.A., M.Phil, B.Ed., ASSISTANT PROFESSOR Page 30
UNIT-2 NOTES
} // end of monitor
Above Program is a monitor solution to the dining-philosopher problem.
condition self[5];
This allows philosopher i to delay herself when she is hungry but is unable to obtain the
chopsticks she needs. We are now in a position to describe our solution to the dining-
philosophers problem. The distribution of the chopsticks is controlled by the monitor Dining
Philosophers. Each philosopher, before starting to eat, must invoke the operation pickup(). This
act may result in the suspension of the philosopher process. After the successful completion of
the operation, the philosopher may eat. Following this, the philosopher invokes the putdown()
operation. Thus, philosopher i must invoke the operations pickup() and putdown() in the
following sequence:
DiningPhilosophers.pickup(i);
...
eat
...
DiningPhilosophers.putdown(i);
It is easy to show that this solution ensures that no two neighbors are eating simultaneously
and that no deadlocks will occur. We note, however, that it is possible for a philosopher to
starve to death.
Scheduling types
Scheduling Objectives
Non-Preemptive Scheduling:
Non-preemptive Scheduling is used when a process terminates, or a process
switchesfrom running to waiting state.
In this scheduling, once the resources (CPU cycles) is allocated to a process, the
processholds the CPU till it gets terminated or it reaches a waiting state.
In case of non-preemptive scheduling does not interrupt a process running
CPU inmiddle of the execution.
Instead, it waits till the process complete its CPU burst time and then it can
allocate theCPU to another process.
Basis for
Preemptive Scheduling Non Preemptive Scheduling
Compariso
n
Once resources are allocated to a
Basic The resources are allocated process, the process holds it till it
to aprocess for a limited time. completes its burst time or switches
towaiting state.
Process can be interrupted Process can not be interrupted till it
Interrupt
inbetween. terminates or switches to waiting
state.
If a high priority process
If a process with long burst time is
Starvation frequently arrives in the ready
running CPU, then another process
queue, low priority process
withless CPU burst time may starve.
maystarve.
Preemptive scheduling
Non-preemptive scheduling does
Overhead has overheads of
nothave overheads.
scheduling theprocesses.
Flexibility Preemptive scheduling is Non-preemptive scheduling is rigid.
flexible.
Preemptive scheduling is Non-preemptive scheduling is not
Cost
costassociated. costassociative.
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 from40% (
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.
In brief:
Arrival Time: Time at which the process arrives in the ready queue. Completion Time:
Time at which process completes its execution. Burst Time: Time required by
a process for CPU execution. Turn Around Time: Time Difference between
completion time and arrival time. Turn Around Time = Completion Time – Arrival Time
Waiting Time(W.T): Time Difference between turnaround time and burst time. Waiting
Time = Turn Around Time – Burst Time
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 2:
Consider the processes P1, P2, P3 given in the below table, arrives for execution
inthe same order, with Arrival Time 0, and given Burst Time,
PROCESS ARRIVAL TIME BURST TIME
P1 0 24
P2 0 3
P3 0 3
Gantt chart
P P P
1 2 3
0 24 27 30
Average Waiting Time = (Total Wait Time) / (Total number of processes) = 51/3 =
Average Turn Around time = (Total Turn Around Time) / (Total number of processes)
= 81 / 3 = 27 ms
Throughput = 3 jobs/30 sec = 0.1 jobs/sec
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
P P P P
1 2 3 4
0 8 12 21 26
Average Waiting Time = (Total Wait Time) / (Total number of processes)= 35/4 =
Average Turn Around time = (Total Turn Around Time) / (Total number of
processes)61/4 = 15.25 ms
Advantages-
SRTF is optimal and guarantees the minimum average waiting time.
It provides a standard for other algorithms since no other algorithm performs
better than it.
Disadvantages-
It can not be implemented practically since burst time of the processes can not
be known in advance.
It leads to starvation for processes with larger burst time.
Priorities can not be set for the processes.
Processes with larger burst time have poor response time.
Example-01:
Consider the set of 5 processes whose arrival time and burst time are given below-
Process Id Arrival time Burst time
P1 3 1
P2 1 4
P3 4 2
P4 0 6
P5 2 3
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
Example-02:
Consider the set of 5 processes whose arrival time and burst time are given below-
Process Id Arrival time Burst time
P1 3 1
P2 1 4
P3 4 2
P4 0 6
P5 2 3
If the CPU scheduling policy is SJF pre-emptive, calculate the average waiting time and
average turnaround time.
Solution-
Gantt Chart-
Now,
Consider the set of 6 processes whose arrival time and burst time are given below-
If the CPU scheduling policy is shortest remaining time first, calculate the average
waiting time and average turnaround time.
Solution-
Gantt Chart-
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Now,
Average Turn Around time = (19 + 12 + 4 + 1 + 5 + 2) / 6 = 43 / 6 = 7.17 unit
Average waiting time = (12 + 7 + 1 + 0 + 3 + 1) / 6 = 24 / 6 = 4 unit
Consider the set of 3 processes whose arrival time and burst time are given below-
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
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:
Consider the set of 4 processes whose arrival time and burst time are given below-
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
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 can not be set for the processes.
Thus, higher value of time quantum is better in terms of number of context switch.
Example-01:
Consider the set of 5 processes whose arrival time and burst time are given below-
Now, we know-
Turn Around time = Exit time – Arrival time
Waiting time = Turn Around time – Burst time
Process Exit time Turn Around time Waiting time
Id
P1 13 13 – 0 = 13 13 – 5 = 8
P2 12 12 – 1 = 11 11 – 3 = 8
P3 5 5–2=3 3–1=2
P4 9 9–3=6 6–2=4
P5 14 14 – 4 = 10 10 – 3 = 7
Now,
Average Turn Around time = (13 + 11 + 3 + 6 + 10) / 5 = 43 / 5 = 8.6 unit
Average waiting time = (8 + 8 + 2 + 4 + 7) / 5 = 29 / 5 = 5.8 unit
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
averagewaiting 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
Now,
Average Turn Around time = (8 + 17 + 4 + 6 + 17 + 13) / 6 = 65 / 6 = 10.84 unit
Average waiting time = (4 + 12 + 2 + 5 + 11 + 10) / 6 = 44 / 6 = 7.33 unit
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
Process Id Exit time Turn Around time Waiting 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
• The waiting time for the process having the highest priority will always be
zero inpreemptive mode.
• The waiting time for the process having the highest priority may not be zero in
non-preemptive mode.
Priority scheduling in preemptive and non-preemptive mode behaves exactly same
underfollowing 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 Burst Priorit
time time y
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
timeand average turnaround time. (Higher number represents higher priority)
Now, we know-
• Turn Around time = Exit time – Arrival time
• Waiting time = Turn Around time – Burst time
Process Id Exit time Turn Around time Waiting time
P1 4 4–0=4 4–4=0
P2 15 15 – 1 = 14 14 – 3 = 11
P3 12 12 – 2 = 10 10 – 1 = 9
P4 9 9–3=6 6–5=1
P5 11 11 – 4 = 7 7–2=5
Now,
• Average Turn Around time = (4 + 14 + 10 + 6 + 7) / 5 = 41 / 5 = 8.2 unit
• Average waiting time = (0 + 11 + 9 + 1 + 5) / 5 = 26 / 5 = 5.2 unit
Problem-02: Consider the set of 5 processes whose arrival time and burst time are
given below-
Process Arrival Burst Priorit
Id time time y
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
Process Id Exit time Turn Around time Waiting 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
What is a Deadlock?
Deadlocks are a set of blocked processes each holding a resource and waiting to acquire a
resource held by another process.
System Model
resource type CPU has two instances. Similarly, the resource type printer may have five
instances.
A process must request a resource before using it and must release there source after
using it. A process may request as many resources as it requires to carry out its designated task.
Obviously, the number of resources requested may not exceed the total number of resources
available in the system. In other words, a process cannot request three printers if the system
has only two. Under the normal mode of operation, a process may utilize a resource in only the
following sequence:
1. Request. The process requests the resource. If the request cannot be granted immediately
(for example, if the resource is being used by another process), then the requesting process
must wait until it can acquire there source.
2. Use. The process can operate on the resource (for example, if the resource is a printer, the
process can print on the printer).
3. Release. The process releases the resource.
The request and release of resources may be system calls like request() and release() device,
open() and close() file, and allocate() and free() memory system calls.
Deadlocks may also involve different resource types. For example, consider a system
with one printer and one DVD drive. Suppose that process Pi is holding the DVD and process
Pj is holding the printer. If Pi requests the printer and Pj requests the DVD drive, a deadlock
occurs.
Deadlock Characterization
In a deadlock, processes never finish executing, and system resources are tied up, preventing
other jobs from starting.
Necessary Conditions
A deadlock situation can arise if the following four conditions hold simultaneously in a
system:
1. Mutual exclusion. At least one resource must be held in a non-sharable mode; that is, only
one process at a time can use the resource. If another process requests that resource, the
requesting process must be delayed until the resource has been released.
2. Hold and wait. A process must be holding at least one resource and waiting to acquire
additional resources that are currently being held by other processes.
3. No preemption. Resources cannot be preempted; that is, a resource can be released only
voluntarily by the process holding it, after that process has completed its task.
4. Circular wait. A set {P0, P1, ..., Pn} of waiting processes must exist such that P0 is waiting for
a resource held by P1, P1 is waiting for a resource held by P2, ..., Pn−1 is waiting for a resource
held by Pn, and Pn is waiting for a resource held by P0.
We emphasize that all four conditions must hold for a deadlock to occur. The circular-wait
condition implies the hold-and-wait condition, so the four conditions are not completely
independent.
Resource-Allocation Graph
Deadlocks can be described more precisely in terms of a directed graph called a system
resource-allocation graph. This graph consists of a set of vertices V and a set of edges E. The
set of vertices V is partitioned into two different types of nodes: P = {P1, P2, ..., Pn}, the set
consisting of all the active processes in the system, and R = {R1, R2, ..., Rm}, the set consisting of
all resource types in the system.
A directed edge from process Pi to resource type Rj is denoted by Pi → Rj ;it signifies that
process Pi has requested an instance of resource type Rj and is currently waiting for that
resource. A directed edge from resource type Rjto process Pi is denoted by Rj → Pi ; it signifies
that an instance of resource type Rj has been allocated to process Pi . A directed edge Pi → Rj
is called a request edge; a directed edge Rj → Pi is called an assignment edge.
process Pi requests an instance of resource type Rj, a request edge is inserted in the resource-
allocation graph. When this request can be fulfilled, the request edge is instantaneously
transformed to an assignment edge. When the process no longer needs access to the resource,
it releases the resource. As a result, the assignment edge is deleted.
The resource-allocation graph shown in Figure 7.1 depicts the following situation.
The sets P, R, and E:
◦ P = {P1, P2, P3}
• Resource instances:
◦ One instance of resource type R1
• Process states:
◦ Process P1 is holding an instance of resource type R2 and is waiting for an instance of
R3.
◦ Process P3 is holding an instance of R3.
Given the definition of a resource-allocation graph, it can be shown that, if the graph contains
no cycles, then no process in the system is deadlocked. If the graph does contain a cycle, then
a deadlock may exist.
K. YUGASENTHILRAJA M.C.A., M.Phil, B.Ed., ASSISTANT PROFESSOR Page 5
UNIT-3 NOTES
If each resource type has exactly one instance, then a cycle implies that a deadlock has
occurred. If the cycle involves only a set of resource types, each of which has only a single
instance, then a deadlock has occurred. Each process involved in the cycle is deadlocked. In this
case, a cycle in the graph is both a necessary and a sufficient condition for the existence of
deadlock.
If each resource type has several instances, then a cycle does not necessarily imply that
a deadlock has occurred. In this case, a cycle in the graph is a necessary but not a sufficient
condition for the existence of deadlock.
To illustrate this concept, we return to the resource-allocation graph depicted in Figure 7.1.
Suppose that process P3 requests an instance of resource type R2. Since no resource instance
is currently available, we add a request edgeP3→ R2 to the graph (Figure 7.2). At this point, two
minimal cycles exist in the system:
P1 → R1 → P2 → R3 → P3 → R2 → P1
P2 → R3 → P3 → R2 → P2
Processes P1, P2, and P3 are deadlocked. Process P2 is waiting for the resourceR3, which is held
by process P3. Process P3 is waiting for either process P1 or process P2 to release resource R2.
In addition, process P1 is waiting for processP2 to release resource R1.
Now consider the resource-allocation graph in Figure 7.3. In this example, we also have a cycle:
P1 → R1 → P3 → R2 → P1
However, there is no deadlock. Observe that process P4 may release its instance of resource
type R2. That resource can then be allocated to P3, breaking the cycle. In summary, if a resource-
allocation graph does not have a cycle, then the system is not in a deadlocked state.If there is
a cycle, then the system may or may not be in a deadlocked state. This observationis important
when we deal with the deadlock problem.
The resource allocation graph is the pictorial representation of the state of a system. As its
name suggests, the resource allocation graph is the complete information about all the
processes which are holding some resources or waiting for some resources.
It also contains the information about all the instances of all the resources whether they
are available or being used by the processes. In Resource allocation graph, the process is
represented by a Circle while the Resource is represented by a rectangle.
Vertices are mainly of two types, Resource and process. Each of them will be
represented by a different shape. Circle represents process while rectangle represents
resource. A resource can have more than one instance. Each instance will be represented by a
dot inside the rectangle.
Edges in RAG are also of two types, one represents assignment and other represents the wait
of a process for a resource. The above image shows each of them. A resource is shown as
assigned to a process if the tail of the arrow is attached to an instance to the resource and the
head is attached to a process. A process is shown as waiting for a resource if the tail of an arrow
is attached to the process while the head is pointing towards the resource.
Example
Let's consider 3 processes P1, P2 and P3, and two types of resources R1 and R2. The
resources are having 1 instance each.
According to the graph, R1 is being used by P1, P2 is holding R2 and waiting for R1, P3 is
waiting for R1 as well as R2.
The graph is deadlock free since no cycle is being formed in the graph.
If a cycle is being formed in a Resource allocation graph where all the resources have the single
instance then the system is deadlocked. In Case of Resource allocation graph with multi-
instanced resource types, Cycle is a necessary condition of deadlock but not the sufficient
condition. The following example contains three processes P1, P2, P3 and three resources R2,
R2, R3. All the resources are having single instances each.
If we analyze the graph then we can find out that there is a cycle formed in the graph since the
system is satisfying all the four conditions of deadlock.
Allocation Matrix
Allocation matrix can be formed by using the Resource allocation graph of a system. In
Allocation matrix, an entry will be made for each of the resource assigned. For Example, in the
following matrix, en entry is being made in front of P1 and below R3 since R3 is assigned to P1.
Process R1 R2 R3
P1 0 0 1
P2 1 0 0
P3 0 1 0
Request Matrix
In request matrix, an entry will be made for each of the resource requested. As in the following
example, P1 needs R1 therefore an entry is being made in front of P1 and below R1.
Process R1 R2 R3
P1 1 0 0
P2 0 1 0
P3 0 0 1
Avial = (0,0,0)
Neither we are having any resource available in the system nor a process going to release. Each
of the process needs at least single resource to complete therefore they will continuously be
holding each one of them. We cannot fulfill the demand of at least one process using the
available resources therefore the system is deadlocked as determined earlier when we
detected a cycle in the graph.
In this approach, The OS doesn't apply any mechanism to avoid or prevent the deadlocks.
Therefore the system considers that the deadlock will definitely occur. In order to get rid of
deadlocks, The OS periodically checks the system for any deadlock. In case, it finds any of the
deadlock then the OS will recover the system using some recovery techniques. The main task
of the OS is detecting the deadlocks. The OS can detect the deadlocks with the help of Resource
allocation graph.
In single instanced resource types, if a cycle is being formed in the system then there will
definitely be a deadlock. On the other hand, in multiple instanced resource type graph,
detecting a cycle is not just enough. We have to apply the safety algorithm on the system by
converting the resource allocation graph into the allocation matrix and request matrix. In order
to recover the system from deadlocks, either OS considers resources or processes.
For Resource
For Process
Kill a process
Killing a process can solve our problem but the bigger concern is to decide which process to
kill. Generally, Operating system kills a process which has done least amount of work until now.
Kill all process
This is not a suggestible approach but can be implemented if the problem becomes very
serious. Killing all process will lead to inefficiency in the system because all the processes will
execute again from starting.
Generally speaking, we can deal with the deadlock problem in one of three ways:
• We can use a protocol to prevent or avoid deadlocks, ensuring that the system will never
enter a deadlocked state.
• We can allow the system to enter a deadlocked state, detect it, and recover.
• We can ignore the problem altogether and pretend that deadlocks never occur in the
system.
The third solution is the one used by most operating systems, including Linux and Windows.
It is then up to the application developer to write programs that handle deadlocks.
To ensure that deadlocks never occur, the system can use either a deadlock prevention
or a deadlock-avoidance scheme. Deadlock prevention provides a set of methods to ensure
that at least one of the necessary conditions (Section7.2.1) cannot hold. These methods prevent
deadlocks by constraining how requests for resources can be made.
Deadlock Prevention
For a deadlock to occur, each of the four necessary conditions must hold. By ensuring that at
least one of these conditions cannot hold, we can prevent the occurrence of a deadlock.
Deadlock Prevention
If we simulate deadlock with a table which is standing on its four legs then we can also simulate
four legs with the four conditions which when occurs simultaneously, cause the deadlock.
However, if we break one of the legs of the table then the table will fall definitely. The
same happens with deadlock, if we can be able to violate one of the four necessary conditions
and don't let them occur together then we can prevent the deadlock.
Let's see how we can prevent each of the conditions.
1. Mutual Exclusion
Mutual section from the resource point of view is the fact that a resource can never be used by
more than one process simultaneously which is fair enough but that is the main reason behind
the deadlock. If a resource could have been used by more than one process at thesame time
then the process would have never been waiting for any resource.
However, if we can be able to violate resources behaving in the mutually exclusive manner then
the deadlock can be prevented.
Spooling
For a device like printer, spooling can work. There is a memory associated with the printer
which stores jobs from each of the process into it. Later, Printer collects all the jobs and print
each one of them according to FCFS. By using this mechanism, the process doesn't have to wait
for the printer and it can continue whatever it was doing. Later, it collects the output when it is
produced.
Although, Spooling can be an effective approach to violate mutual exclusion but it suffers from
two kinds of problems.
1. This cannot be applied to every resource.
2. After some point of time, there may arise a race condition between the processes to
get space in that spool.
We cannot force a resource to be used by more than one process at the same time since it will
not be fair enough and some serious problems may arise in the performance. Therefore, we
cannot violate mutual exclusion for a process practically.
However, we have to find out some mechanism by which a process either doesn't hold
any resource or doesn't wait. That means, a process must be assigned all the necessary
resources before the execution starts. A process must not wait for any resource once the
execution has been started.
!(Hold and wait) = !hold or !wait (negation of hold and wait is, either you don't hold or
you don't wait)
This can be implemented practically if a process declares all the resources initially.
However, this sounds very practical but can't be done in the computer system because a
process can't determine necessary resources initially. Process is the set of instructions which
are executed by the CPU. Each of the instruction may demand multiple resources at the multiple
times. The need cannot be fixed by the OS.
3. No Preemption
Deadlock arises due to the fact that a process can't be stopped once it starts. However, if we
take the resource away from the process which is causing deadlock then we can prevent
deadlock.
This is not a good approach at all since if we take a resource away which is being used
by the process then all the work which it has done till now can become inconsistent. Consider
a printer is being used by any process. If we take the printer away from that process and assign
it to some other process then all the data which has been printed can become inconsistent and
ineffective and also the fact that the process can't start printing again from where it has left
which causes performance inefficiency.
4. Circular Wait
To violate circular wait, we can assign a priority number to each of the resource. A process can't
request for a lesser priority resource. This ensures that not a single process can request a
resource which is being utilized by some other process and no cycle will be formed.
Among all the methods, violating Circular wait is the only approach that can be implemented
practically.
Deadlock Avoidance
An alternative method for avoiding deadlocks is to require additional information about how
resources are to be requested. In this the system consider the resources currently available, the
resources currently allocated to each process, and the future requests and releases of each
process. A deadlock-avoidance algorithm dynamically examines the resource-allocation state
to ensure that a circular-wait condition can never exist. The resource-allocation state is defined
by the number of available and allocated resources and the maximum demands of the
processes.
1) Resource-Allocation-Graph Algorithm
2) Banker’s Algorithm
Safe State
A state is safe if the system can allocate resources to each process (up to its maximum) in some
order and still avoid a deadlock. More formally, a system is in a safe state only if there exists a
safe sequence. A sequence of processes<P1, P2, ..., Pn > is a safe sequence for the current
allocation state if, for each Pi , the resource requests that Pi can still make can be satisfied by
the currently available resources plus the resources held by all P j ,with j < i. Inthis situation, if
the resources that Pi needs are not immediately available, then Pi can wait until all P j have
finished. When they have finished, Pi can obtain all of its needed resources, complete its
designated task, return its allocated resources, and terminate. When Pi terminates, Pi +1 can
obtain its needed resources, and so on. If no such sequence exists, then the system state is said
to be unsafe.
Deadlock avoidance
In deadlock avoidance, the request for any resource will be granted if the resulting state of the
system doesn't cause deadlock in the system. The state of the system will continuously be
checked for safe and unsafe states. In order to avoid deadlocks, the process must tell OS, the
maximum number of resources a process can request to complete its execution.
The simplest and most useful approach states that the process should declare the
maximum number of resources of each type it may ever need. The Deadlock avoidance
algorithm examines the resource allocations so that there can never be a circular wait
condition.
K. YUGASENTHILRAJA M.C.A., M.Phil, B.Ed., ASSISTANT PROFESSOR Page 16
UNIT-3 NOTES
A 3 0 2 2
B 0 0 1 1
C 1 1 1 0
D 2 1 4 0
A 1 1 0 0
B 0 1 1 2
C 1 2 1 0
D 2 1 1 2
1. E = (7 6 8 4)
2. P = (6 2 8 3)
3. A = (1 4 0 1)
Above tables and vector E, P and A describes the resource allocation state of a system. There
are 4 processes and 4 types of the resources in a system. Table 1 shows the instances of each
resource assigned to each process. Table 2 shows the instances of the resources, each process
still needs. Vector E is the representation of total instances of each resource in the system.
Vector P represents the instances of resources that have been assigned to processes. Vector A
represents the number of resources that are not in use. A state of the system is called safe if the
system can allocate all the resources requested by all the processes without entering into
deadlock. If the system cannot fulfill the request of all processes then the state of the system
is called unsafe. The key of Deadlock avoidance approach is when the request is made for
resources then the request must only be approved in the case if the resulting state is also a safe
state.
1. Available
It is an array of length m. It represents the number of available resources of each type.
If Available[j] = k, then there are k instances available, of resource type R(j).
2. Max
It is an n x m matrix which represents the maximum number of instances of each resource that
a process can request. If Max[i][j] = k, then the process P(i) can request atmost k
instances of resource type R(j).
3. Allocation
It is an n x m matrix which represents the number of resources of each type currently allocated
to each process. If Allocation[i][j] = k, then process P(i) is currently allocated k instances
of resource type R(j).
4. Need
It is an n x m matrix which indicates the remaining resource needs of each process.If
Need[i][j] = k, then process P(i) may need k more instances of resource type R(j) to complete
its task.
Need[i][j] = Max[i][j] - Allocation [i][j]
This step is done because the system needs to assume that resources have been allocated. So
there will be less resources available after allocation. The number of allocated instances will
increase. The need of the resources by the process will reduce. That's what is represented by
the above three operations.
After completing the above three steps, check if the system is in safe state by applying
the safety algorithm. If it is in safe state, proceed to allocate the requested resources. Else, the
process has to wait longer.
Safety Algorithm
1. Let Work and Finish be vectors of length m and n, respectively. Initially,
2. Work = Available
3. Finish[i] =false for i = 0, 1, ... , n - 1.
This means, initially, no process has finished and the number of available resources is
represented by the Available array.
4. Find an index i such that both
5. Finish[i] ==false
6. Needi <= Work
If there is no such i present, then proceed to step 4.
It means, we need to find an unfinished process whose need can be satisfied by the
available resources. If no such process exists, just go to step 4.
7. Perform the following:
8. Work = Work + Allocation;
9. Finish[i] = true;
Go to step 2.
When an unfinished process is found, then the resources are allocated and the process is
marked finished. And then, the loop is repeated to check the same for all other processes.
10. If Finish[i] == true for all i, then the system is in a safe state.
That means if all processes are finished, then the system is in safe state.
Example:
Considering a system with five processes P0 through P4 and three resources types A, B,
C. Resource type A has 10 instances, B has 5 instances and type C has 7 instances.
Suppose at time t0 following snapshot of the system has been taken:
Question2. Is the system in safe state? If Yes, then what is the safe sequence?
Applying the Safety algorithm on the given system,
Question3. What will happen if process P1 requests one additional instance of resource
type A and two instances of resource type C?
We must determine whether this new system state is safe. To do so, we again execute Safety
algorithm on the above data structures.
Hence the new system state is safe, so we can immediately grant the request for process P1 .
Example2
Assuming that the system distinguishes between four types of resources, (A, B, C and D), the
following is an example of how those resources could be distributed. Note that this example
shows the system at an instant before a new request for resources arrives. Also, the types and
number of resources are abstracted. Real systems, for example, would deal with much larger
quantities of each resource.
If deadlock prevention and avoidance are not done properly, as deadlock may occur and only
things left to do is to detect the recover from the deadlock.
If all resource types has only single instance, then we can use a graph called wait-for-
graph, which is a variant of resource allocation graph. Here, vertices represent processes and
a directed edge from P1 to P2 indicate that P1 is waiting for a resource held by P2. Like in the
case of resource allocation graph, a cycle in a wait-for-graph indicate a deadlock. So the system
can maintain a wait-for-graph and check for cycles periodically to detect any deadlocks.
The wait-for-graph is not much useful if there are multiple instances for a resource, as
a cycle may not imply a deadlock. In such a case, we can use an algorithm similar to Banker’s
algorithm to detect deadlock. We can see if further allocations can be made on not based on
When a detection algorithm determines that a deadlock exists, several alter-natives are
available. One possibility is to inform the operator that a deadlock has occurred and to let the
operator deal with the deadlock manually. Another possibility is to let the system recover from
the deadlock automatically. There are two options for breaking a deadlock. One is simply to
abort one or more processes to break the circular wait. The other is to preempt some resources
from one or more of the deadlocked processes.
Process Termination
To eliminate deadlocks by aborting a process, we use one of two methods. In both methods, the
system reclaims all resources allocated to the terminated processes.
• Abort all deadlocked processes. This method clearly will break the deadlock cycle, but at great
expense. The deadlocked processes may have computed for a long time, and the results of these
partial computations must be discarded and probably will have to be recomputed later.
• Abort one process at a time until the deadlock cycle is eliminated. This method incurs
considerable overhead, since after each process is aborted, a deadlock-detection algorithm
must be invoked to determine whether any processes are still deadlocked.
MEMORY MANAGEMENT
In computer each process has a separate memory space. Separate per-process memory space
protects the processes from each other and is fundamental to having multiple processes loaded
in memory for concurrent execution. To separate memory spaces, we need the ability to
determine the range of legal addresses that the process may access and to ensure that the
process can access only these legal addresses. We can provide this protection by using two
registers, usually a base and a limit, as illustrated in Figure 8.1.The base register holds the
smallest legal physical memory address; the limit register specifies the size of the range. For
example, if the base register holds300040 and the limit register is 120900, then the program
can legally access all addresses from 300040 through 420939 (inclusive).
The operating system takes care of mapping the logical addresses to physical addresses at the
time of memory allocation to the program.
The runtime mapping from virtual to physical address is done by the memory
management unit (MMU) which is a hardware device. MMU uses following mechanism to
convert virtual address to physical address.
• The value in the base register is added to every address generated by a user process,
which is treated as offset at the time it is sent to memory. For example, if the base register value
is 10000, then an attempt by the user to use address location 100 will be dynamically
reallocated to location 10100.
• The user program deals with virtual addresses; it never sees the real physical addresses.
The choice between Static or Dynamic Loading is to be made at the time of computer program
being developed. If you have to load your program statically, then at the time of compilation,
the complete programs will be compiled and linked without leaving any external program or
module dependency. The linker combines the object program with other necessary object
modules into an absolute program, which also includes logical addresses.
If you are writing a dynamically loaded program, then your compiler will compile the
program and for all the modules which you want to include dynamically, only references will
be provided and rest of the work will be done at the time of execution. At the time of loading,
with static loading, the absolute program (and data) is loaded into memory in order for
execution to start. If you are using dynamic loading, dynamic routines of the library are stored
on a disk in relocatable form and are loaded into memory only when they are needed by the
program.
As explained above, when static linking is used, the linker combines all other modules needed
by a program into a single executable program to avoid any runtime dependency.
When dynamic linking is used, it is not required to link the actual module or library with
the program, rather a reference to the dynamic module is provided at the time of compilation
and linking. Dynamic Link Libraries (DLL) in Windows and Shared Objects in Unix are good
examples of dynamic libraries.
Address Binding
Usually, a program resides on a disk as a binary executable file. To be executed, the program
must be brought into memory and placed within a process. Depending on the memory
management in use, the process may be moved between disk and memory during its execution.
The processes on the disk that are waiting to be brought into memory for execution form the
input queue.
In most cases, a user program goes through several steps—some of which may be
optional—before being executed (Figure 8.3). Addresses may be represented in different ways
during these steps. Addresses in the source program are generally symbolic (such as the
variable count). A compiler typically binds these symbolic addresses to relocatable addresses
(such as “14 bytes from the beginning of this module”). The linkage editor or loader in turn
binds the relocatable addresses to absolute addresses (such as 74014). Each binding is a
• Compile time. If you know at compile time where the process will reside in memory, then
absolute code can be generated. For example, if you know that a user process will reside
starting at location R, then the generated compiler code will start at that location and extend
up from there. If, at some later time, the starting location changes, then it will be necessary to
recompile this code. The MS-DOS .COM-format programs are bound at compile time.
• Load time. If it is not known at compile time where the process will reside in memory, then
the compiler must generate relocatable code. In this case, final binding is delayed until load
time. If the starting address changes, we need only reload the user code to incorporate this
changed value.
• Execution time. If the process can be moved during its execution from one memory segment
to another, then binding must be delayed until run time. Special hardware must be available
for this scheme to work. Most general-purpose operating systems use this method.
The total time taken by swapping process includes the time it takes to move the entire process
to a secondary disk and then to copy the process back to memory, as well as the time the
process takes to regain main memory.
Let us assume that the user process is of size 2048KB and on a standard hard disk
where swapping will take place has a data transfer rate around 1 MB per second. The actual
transfer of the 1000K process to or from memory will take
Now considering in and out time, it will take complete 4000 milliseconds plus other
overhead where the process competes to regain main memory.
MemoryAllocation
Main memory usually has two partitions −
• Low Memory − Operating system resides in this memory.
• High Memory − User processes are held in high memory.
Operating system uses the following memory allocation mechanism.
1 Single-partition allocation
In this type of allocation, relocation-register scheme is used to protect user
processes from each other, and from changing operating-system code and data.
Relocation register contains value of smallest physical address whereas limit
register contains range of logical addresses. Each logical address must be less
than the limit register.
2 Multiple-partition allocation
In this type of allocation, main memory is divided into a number of fixed-sized
partitions where each partition should contain only one process. When a
partition is free, a process is selected from the input queue and is loaded into
the free partition. When the process terminates, the partition becomes available
for another process.
Memory Protection
MemoryAllocation
Memory allocation is a process by which computer programs are assigned memory or space.
It is of three types :
The contiguous memory allocation scheme can be implemented in operating systems with the
help of two registers, known as the base and limit registers. When a process is executing in
main memory, its base register contains the starting address of the memory location where the
process is executing, while the amount of bytes consumed by the process is stored in the limit
register.
A process does not directly refer to the actual address for a corresponding memory
location. Instead, it uses a relative address with respect to its base register. All addresses
referred by a program are considered as virtual addresses. The CPU generates the logical or
virtual address, which is converted into an actual address with the help of the memory
management unit (MMU). The base address register is used for address translation by the MMU.
Thus, a physical address is calculated as follows:
The address of any memory location referenced by a process is checked to ensure that
it does not refer to an address of a neighboring process. This processing security is handled by
the underlying operating system. One disadvantage of contiguous memory allocation is that
the degree of multiprogramming is reduced due to processes waiting for free memory.
Operating System keeps track of available free memory areas. There are three approaches to
select a free partition from the set of available blocks.
First Fit:
It allocates the first free large area whose size is >= program size. Searching may start from
either beginning of the list or where previous first-fit search ended. Limitation of this
technique is that it may split a free area repeatedly and produce smaller size of blocks that may
consider as external fragmentation.
Best Fit:
It allocates the smallest free area with size >= program size. We have to search the entire free
list to find out the smallest free hole so it has higher allocation cost. Limitation of this technique
is that in long run it too may produce numerous unusable small free areas. It also suffers from
higher allocation cost because it has to process entire free list at every allocation.
The worst fit technique is a compromise between these two techniques. It remembers the entry
of last allocation. It searches the free list starting from the previous allocation for the first free
area of size >= program size. The first fit technique is better than best fit. Both first fit and next
fit performs better than best fit.
Example:A free list contains three free areas of size 200, 170 and 500 bytes respectively (figure
a). Processes sends allocation requests for 100, 50 and 400 bytes.
The first fit technique will allocate 100 and 50 bytes from the first free area leaving a free
area of 50 bytes. It allocates 400 bytes from the third free area.
The best fit technique will allocate 100 and 50 bytes from the second free area leaving a free
area of 20 bytes. The next fit technique allocates 100, 50 and 400 bytes from the three free
areas.
Fragmentation
As processes are loaded and removed from memory, the free memory space is broken into
little pieces. It happens after sometimes that processes cannot be allocated to memory blocks
considering their small size and memory blocks remains unused. This problem is known as
Fragmentation.
Fragmentation is of two types −
1 External fragmentation
Total memory space is enough to satisfy a request or to reside a process in it,
but it is not contiguous, so it cannot be used.
2 Internal fragmentation
Memory block assigned to process is bigger. Some portion of memory is left
unused, as it cannot be used by another process.
The following diagram shows how fragmentation can cause waste of memory and a
compaction technique can be used to create more free memory out of fragmented memory −
External fragmentation can be reduced by compaction or shuffle memory contents to place all
free memory together in one large block. To make compaction feasible, relocation should be
dynamic. The internal fragmentation can be reduced by effectively assigning the smallest
partition but large enough for the process.
Difference between Internal and External fragmentation
Internal Fragmentation
1. When a process is allocated more memory than required, few space is left unused
and this is called as INTERNAL FRAGMENTATION.
2. It occurs when memory is divided into fixed-sized partitions.
3. It can be cured by allocating memory dynamically or having partitions of different
sizes.
External Fragmentation
1. After execution of processes when they are swapped out of memory and othersmaller
processes replace them, many small non contiguous(adjacent) blocks of unused
spaces are formed which can serve a new request if all of them are put together but
as they are not adjacent to each other a new request can't be served and this is known
as EXTERNAL FRAGMENTATION.
2. It occurs when memory is divided into variable-sized partitions based on size of
process.
3. It can be cured by Compaction, Paging and Segmentation.
Internal Fragmentation
External Fragmentation
Segmentation
Segmentation is a memory management technique in which each job is divided into several
segments of different sizes, one for each module that contains pieces that perform related
functions. Each segment is actually a different logical address space of the program.
When a process is to be executed, its corresponding segmentation are loaded into non-
contiguous memory though every segment is loaded into a contiguous block of available
memory. Segmentation memory management works very similar to paging but here segments
are of variable-length where as in paging pages are of fixed size.
A program segment contains the program's main function, utility functions, data
structures, and so on. The operating system maintains a segment map table for everyprocess
and a list of free memory blocks along with segment numbers, their size and corresponding
memory locations in main memory. For each segment, the table stores the starting address of
the segment and the length of the segment. A reference to a memory location includes a value
that identifies a segment and an offset.
Segmentation Hardware
Although the programmer can now refer to objects in the program by a two-dimensional
address, the actual physical memory is still, of course, a one-dimensional sequence of bytes.
Thus, we must define an implementation to map two-dimensional user-defined addresses
into one-dimensional physical addresses. This mapping is effected by a 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, and the segment limit
specifies the length of the segment.
The use of a segment table is illustrated in Figure 8.8. 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, we 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 thus essentially an arrayof base –
limit register pairs.
We have five segments numbered from 0 through 4. The segments are stored in physical
memory as shown. 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). For example, 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 to3200 (the base of segment 3) + 852 = 4052. A reference to
byte 1222 of segment0 would result in a trap to the operating system, as this segment is only
1,000bytes long.
Paging
A computer can address more memory than the amount physically installed on the system.
This extra memory is actually called virtual memory and it is a section of a hard that's set up
to emulate the computer's RAM. Paging technique plays an important role in implementing
virtual memory.
Similarly, main memory is divided into small fixed-sized blocks of (physical) memory
called frames and the size of a frame is kept the same as that of a page to have optimum
utilization of the main memory and to avoid external fragmentation.
Address Translation
Page address is called logical address and represented by page numberand the offset.
Frame address is called physical address and represented by a frame number and
the offset.
A data structure called page map table is used to keep track of the relation between a page
of a process to a frame in physical memory.
When the system allocates a frame to any page, it translates this logical address into a physical
address and create entry into the page table to be used throughout execution of the program.
When a process is to be executed, its corresponding pages are loaded into any available
memory frames. Suppose you have a program of 8Kb but your memory can accommodate only
5Kb at a given point in time, then the paging concept will come into picture. When a computer
runs out of RAM, the operating system (OS) will move idle or unwanted pages of memory to
secondary memory to free up RAM for other processes and brings them back when needed by
the program.
This process continues during the whole execution of the program where the OSkeeps
removing idle pages from the main memory and write them onto the secondary memory and
bring them back when required by the program.
• Page table requires extra memory space, so may not be good for a system having small
RAM.
Paging VS Segmentation
S
Paging Segmentation
No.
1 Non-Contiguous memory allocation Non-contiguous memory allocation
Logical address is divided into page number and page Logical address is divided into segment
8
offset number and segment offset
Segment Table maintains the segment
9 Page table is used to maintain the page information.
information
Segment table entry has the base address
Page table entry has the frame number and some flag
10 of the segment and some protection bits for
bits to represent details about pages.
the segments.
Virtual Memory
A computer can address more memory than the amount physically installed on the system. This
extra memory is actually called virtual memory and it is a section of a hard disk that's setup to
emulate the computer's RAM.
The main visible advantage of this scheme is that programs can be larger than physical
memory. Virtual memory serves two purposes. First, it allows us to extend the use of physical
memory by using disk. Second, it allows us to have memory protection, because each virtual
address is translated to a physical address.
Following are the situations, when entire program is not required to be loaded fully in main
memory.
➢ User written error handling routines are used only when an error occurred in the data
or computation.
➢ Certain options and features of a program may be used rarely.
➢ Many tables are assigned a fixed amount of address space even though only a small
amount of the table is actually used.
➢ The ability to execute a program that is only partially in memory would counter many
benefits.
➢ Less number of I/O would be needed to load or swap each user program into memory.
➢ A program would no longer be constrained by the amount of physical memory that is
available.
➢ Each user program could take less physical memory, more programs could be run the
same time, with a corresponding increase in CPU utilization and throughput.
Demand Paging
A demand paging system is quite similar to a paging system with swapping where processes
reside in secondary memory and pages are loaded only on demand, not in advance. When a
context switch occurs, the operating system does not copy any of the old program’s pages out
to the disk or any of the new program’s pages into the main memory Instead, it just begins
executing the new program after loading the first page and fetches that program’s pages as they
are referenced.
While executing a program, if the program references a page which is not available in the main
memory because it was swapped out a little ago, the processor treats this invalid memory
reference as a page fault and transfers control from the program to the operating system to
demand the page back into the memory.
Advantages
Disadvantages
Number of tables and the amount of processor overhead for handling page interrupts are
greater than in the case of the simple paged management techniques.
Page replacement algorithms are the techniques using which an Operating System decides
which memory pages to swap out, write to disk when a page of memory needs to be allocated.
Paging happens whenever a page fault occurs and a free page cannot be used for allocation
purpose accounting to reason that pages are not available or the number of free pages is lower
than required pages.
When the page that was selected for replacement and was paged out, is referenced
again, it has to read in from disk, and this requires for I/O completion. This process determines
the quality of the page replacement algorithm: the lesser the time waiting for page-ins, the
better is the algorithm.
A page replacement algorithm looks at the limited information about accessing the
pages provided by hardware, and tries to select which pages should be replaced to minimize
the total number of page misses, while balancing it with the costs of primary storage and
processor time of the algorithm itself. There are many different page replacement algorithms.
We evaluate an algorithm by running it on a particular string of memory reference and
computing the number of page faults,
Reference String
The string of memory references is called reference string. Reference strings are generated
artificially or by tracing a given system and recording the address of each memory reference.
The latter choice produces a large number of data, where we note two things.
For a given page size, we need to consider only the page number, not the entire address. If we
have a reference to a page p, then any immediately following references to page p will never
cause a page fault. Page p will be in memory after the first reference; the immediately following
references will not fault.
Oldest page in main memory is the one which will be selected for replacement.
Easy to implement, keep a list, replace pages from the tail and add new pages at the head.
An optimal page-replacement algorithm has the lowest page-fault rate of all algorithms. An
optimal page-replacement algorithm exists, and has been called OPT or MIN.
Replace the page that will not be used for the longest period of time. Use the time when a
page is to be used.
Page which has not been used for the longest time in main memory is the one which will be
selected for replacement.
Easy to implement, keep a list, replace pages by looking back into time.
If the referred page is not present in the main memory then there will be a miss and the concept
is called Page miss or page fault. The CPU has to access the missed page from the secondary
memory. If the number of page fault is very high then the effective access time of the system
will become very high.
What is Thrashing?
If the number of page faults is equal to the number of referred pages or the number of page
faults are so high so that the CPU remains busy in just reading the pages from the secondary
memory then the effective access time will be the time taken by the CPU to read one word from
the secondary memory and it will be so high. The concept is called thrashing.
If the page fault rate is PF %, the time taken in getting a page from the secondary
memory and again restarting is S (service time) and the memory access time is ma then the
effective access time can be given as;
Thrashing
A process that is spending more time paging than executing is said to be thrashing. In other
words it means, that the process doesn't have enough frames to hold all the pages for its
execution, so it is swapping pages in and out very frequently to keep executing. Sometimes, the
pages which will be required in the near future have to be swapped out.
Initially when the CPU utilization is low, the process scheduling mechanism, to increase
the level of multiprogramming loads multiple processes into the memory at the same time,
allocating a limited amount of frames to each process. As the memory fills up, process starts to
spend a lot of time for the required pages to be swapped in, again leading to low CPU utilization
because most of the proccesses are waiting for pages. Hence the schedulerloads more processes
to increase CPU utilization, as this continues at a point of time the complete system comes to a
stop.
To prevent thrashing we must provide processes with as many frames as they really need "right
now".
UNIT – IV
STORAGE MANAGEMENT: File system-Concept of a file, access methods, directory structure,
file system mounting, file sharing, protection. (T1: Ch-10) SECONDARY-STORAGE
STRUCTURE: Overview of mass storage structure, disk structure, disk attachment, disk
scheduling algorithms, swap space management, stable storage implementation, and tertiary
storage structure (T1: Ch-12).
File Concept
The operating system abstracts from the physical properties of its storage devices to define a
logical storage unit, the file. Files are mapped by the operating system onto physical devices.
These storage devices are usually nonvolatile, so the contents are persistent between system
reboots.
A file is a named collection of related information that is recorded on secondary storage.
From a user’s perspective, a file is the smallest allotment of logical secondary storage.
Commonly, files represent programs (both source and object forms) and data. Data files may
be numeric, alphabetic, alphanumeric, or binary.
The information in a file is defined by its creator. Many different types of information
maybe stored in a file—source or executable programs, numeric or text data, photos, music,
video, and so on. A file has a certain defined structure, which depends on its type. A text file is
a sequence of characters organized into lines (and possibly pages). A source file is a sequence
of functions, each of which is further organized as declarations followed by executable
statements. An executable file is a series of code sections that the loader can bring into
memory and execute.
File Attributes
file’s attributes vary from one operating system to another but typically consist of these:
• Name. The symbolic file name is the only information kept in human readable form.
• Identifier. This unique tag, usually a number, identifies the file within the file system; it is
the non-human-readable name for the file.
• Type. This information is needed for systems that support different types of files.
• Location. This information is a pointer to a device and to the location of the file on that
device.
• Size. The current size of the file (in bytes, words, or blocks) and possibly the maximum
allowed size are included in this attribute.
• Protection. Access-control information determines who can do reading, writing, executing,
and so on.
• Time, date, and user identification. This information may be kept for creation, last
modification, and last use. These data can be useful for protection, security, and usage
monitoring.
File Operations
Creating a file.
Writing a file: 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: system needs to keep a read pointer to the location in the file where the next
read is to take place. the current operation location can be kept as a per-process current file-
position pointer.
Repositioning within a file: This file operation is also known as a file seek.
Deleting a file
Truncating a file
Most of the file operations mentioned involve searching the directory for the entry associated
with the named file. To avoid this constant searching, many systems require that an open()
system call be made before a file is first used. The operating system keeps a table, called the
open-file table, containing information about all open files.
Typically, the open-file table also has an open count associated with each file toindicate
how many processes have the file open. Each close() decreases this open count, and when the
open count reaches zero, the file is no longer in use, and the file’s entry is removed from the
open-file table.
Some operating systems provide facilities for locking an open file (or sections of a file). File
locks allow one process to lock a file and prevent other processes from gaining access to it. A
shared lock is akin to a reader lock in that several processes can acquire the lock concurrently.
An exclusive lock behaves like a writer lock; only one process at a time can acquire such a lock.
Access Methods
Files store information. When it is used, this information must be accessed and read into
computer memory. The information in the file can be accessed in several ways. Some systems
provide only one access method for files. while others support many access methods, and
choosing the right one for a particular application is a major design problem.
There are three ways to access a file into computer system: Sequential Access, Direct Access,
Index sequential Method.
Sequential Access
The simplest access method is sequential access. Information in the file is processed in order,
one record after the other. Reads and writes make up the bulk of the operations on a file. A read
operation—read next()—reads the next portion of the file and automaticallyadvances a file
pointer, which tracks the I/O location. Similarly, the write operation—write next()—appends
to the end of the file and advances to the end of the newly written material (the new end of file).
Key points:
1. Data is accessed one record right after another record in an order.
2. When we use read command, it move ahead pointer by one
3. When we use write command, it will allocate memory and move the pointer to
the end of the file
4. Such a method is reasonable for tape.
Direct Access
Another method is direct access (or relative access). Here, a file is made up of fixed-length
logical records that allow programs to read and write records rapidly in no particular order.
The direct-access method is based on a disk model of a file, since disks allow random access
to any file block.
For direct access, the file is viewed as a numbered sequence of blocks or records. Thus,
we may read block 14, then read block 53, and then write block 7. There are no restrictions on
the order of reading or writing for a direct-access file. For the direct-access method, the file
operations must be modified to include the block number as a parameter. Thus, we have
read(n), where n is the block number, rather than read next(), and write(n) rather than write
next().
The block number provided by the user to the operating system is normally a relative
block number. A relative block number is an index relative to the beginning of the file. Thus,
the first relative block of the file is 0, the next is1, and so on. When file is used, information is
read and accessed into computer memory and there are several ways to accesses these
information of the file.
Partitioning is useful for limiting the sizes of individual file systems, putting multiple
file-system types on the same device, or leaving part of the device available for other uses, such
as swap space or unformatted (raw) disk space. A file system can be created on each of these
parts of the disk. Any entity containing a file system is generally known as a volume. The
volume may be a subset of a device, a whole device, or multiple devices linked together into a
RAID set. Each volume can be thought of as a virtual disk. Volumes can also store multiple
operating systems, allowing a system to boot and run more than one operating system.
Each volume that contains a file system must also contain information about the filesin
the system. This information is kept in entries in a device directory or volume table of contents.
The device directory (more commonly known simply as the directory) recordsinformation—
such as name, location, size, and type—for all files on that volume. Figure 11.7 shows a typical
file-system organization.
Directory Overview
The directory can be viewed as a symbol table that translates file names into their
directory entries. If we take such a view, we see that the directory itself can be organized in
many ways. The organization must allow us to insert entries, to delete entries, to search for a
named entry, and to list all the entries in the directory.
What is a directory?
Directory can be defined as the listing of the related files on the disk. The directory may store
some or the entire file attributes. To get the benefit of different file systems on the different
operating systems, A hard disk can be divided into the number of partitions of different sizes.
The partitions are also called volumes or mini disks.
Each partition must have at least one directory in which, all the files of the partition can
be listed. A directory entry is maintained for each file in the directory which stores all the
information related to that file.
A directory can be viewed as a file which contains the Meta data of the bunch of files.
Disadvantages
1. We cannot have two files with the same name.
2. The directory may be very big therefore searching for a file may take so much time.
3. Protection cannot be implemented for multiple users.
4. There are no ways to group same kind of files.
5. Choosing the unique name for every file is a bit complex and limits the number of files
in the system because most of the Operating System limits the number of characters
used to construct the file name.
In the two-level directory structure, each user has his own user file directory (UFD). The
UFDs have similar structures, but each lists only the files of a single user. When a user job starts
or a user logs in, the system’s master file directory (MFD) is searched. The MFD is indexed by
user name or account number, and each entry points to the UFD for that user. Every file in the
system has a path name. To name a file uniquely, a user must know the path name of the file
desired.
▪ There are two ways to specify a file path:
Absolute Path
▪ In this path we can reach to a specified file from the main or root directory.
▪ In this case current directory is not involved; file path is specified starting from the
root directory.
Relative Path
▪ The user working in any directory that directory is called current directory.
▪ To reach to a specified file we have to search from the current directory.
Each user has its own directory and it cannot enter in the other user's directory.
However, the user has the permission to read the root's data but he cannot write or modify this.
Only administrator of the system has the complete access of root directory.
Searching is more efficient in this directory structure. The concept of current working
directory is used. A file can be accessed by two types of path, either relative or absolute. In tree
structured directory systems, the user is given the privilege to create the files as well as
directories.
These kinds of directory graphs can be made using links or aliases. We can have
multiple paths for a same file. Links can either be symbolic (logical) or hard link (physical).
If a file gets deleted in acyclic graph structured directory system, then
1. In the case of soft link, the file just gets deleted and we are left with a dangling pointer.
2. In the case of hard link, the actual file will be deleted only if all the references to it gets
deleted.
File Systems
File system is the part of the operating system which is responsible for file management. It
provides a mechanism to store the data and access to the file contents including data and
programs. Some Operating systems treats everything as a file for example Ubuntu.
The File system takes care of the following issues
o File Structure
We have seen various data structures in which the file can be stored. The task of the file
system is to maintain an optimal file structure.
o Recovering Free space
Whenever a file gets deleted from the hard disk, there is a free space created in the disk.
There can be many such spaces which need to be recovered in order to reallocate them
to other files.
o disk space assignment to the files
The major concern about the file is deciding where to store the files on the hard disk.
o tracking data location
A File may or may not be stored within only one block. It can be stored in the non
contiguous blocks on the disk. We need to keep track of all the blocks on which the part
of the files reside.
File-System Mounting
• The basic idea behind mounting file systems is to combine multiple file systems into one
large tree structure.
• The mount command is given a file system to mount and a mount point ( directory ) on
which to attach it.
• Once a file system is mounted onto a mount point, any further references to that
directory actually refer to the root of the mounted file system.
• Any files ( or sub-directories ) that had been stored in the mount point directory prior
to mounting the new file system are now hidden by the mounted file system, and are no
longer available. For this reason some systems only allow mounting onto empty
directories.
• File systems can only be mounted by root, unless root has previously configured certain
file systems to be mountable onto certain pre-determined mount points. ( E.g. root may
allow users to mount floppy file systems to /mnt or something like it. ) Anyone can run
the mount command to see what file systems are currently mounted.
• File systems may be mounted read-only, or have other restrictions imposed.
Figure 11.14 - File system. (a) Existing system. (b) Unmounted volume.
File Sharing
Multiple Users
• On a multi-user system, more information needs to be stored for each file:
o The owner ( user ) who owns the file, and who can control its access.
o The group of other user IDs that may have some special access to the file.
o What access rights are afforded to the owner ( User ), the Group, and to the rest
of the world ( the universe, a.k.a. Others. )
Protection
• Files must be kept safe for reliability ( against accidental damage ), and protection
( against deliberate malicious access. ) The former is usually managed with backup
copies.
• One simple protection scheme is to remove all access to a file. However this makes the
file unusable, so some sort of controlled access must be arranged.
Access Control
In 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 technique has two undesirable consequences:
• Constructing such a list may be a tedious and unrewarding task, especially if we do not know in
advance the list of users in the system.
• The directory entry, previously of fixed size, now must be of variable size, resulting in more
complicated space management.
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.
To illustrate, consider a person, Sara, who is writing a new book. She has hired three
graduate students (Jim, Dawn, and Jill) to help with the project. The text of the book is kept in
a file named book.tex. The protection associated with this file is as follows:
• Sara should be able to invoke all operations on the file.
• Jim, Dawn, and Jill should be able only to read and write the file; they should not be allowed
to delete the file.
• All other users should be able to read, but not write, the file. (Sara is interested in letting as
many people as possible read the text so that she can obtain feedback.)
Types of Access
• The following low-level operations are often controlled:
Write
W ( change ) file Change directory contents. Required to create or delete files.
contents.
• In addition there are some special bits that can also be applied:
o The set user ID ( SUID ) bit and/or the set group ID ( SGID ) bits applied to
executable files temporarily change the identity of whoever runs the program to
match that of the owner / group of the executable program. This allows users
running specific programs to have access to files ( while running that program
) to which they would normally be unable to access. Setting of these two bits is
usually restricted to root, and must be done with caution, as it introduces a
potential security leak.
o The sticky bit on a directory modifies write permission, allowing users to only
delete files for which they are the owner. This allows everyone to create files in
/tmp, for example, but to only delete files which they have created, and not
anyone else's.
o The SUID, SGID, and sticky bits are indicated with an S, S, and T in the positions
for execute permission for the user, group, and others, respectively. If the letter
is lower case, ( s, s, t ), then the corresponding execute permission is not also
given. If it is upper case, ( S, S, T ), then the corresponding execute permission
IS given.
o The numeric form of chmod is needed to set these advanced bits.
A read–write head “flies” just above each surface of every platter. The heads are attached to a
disk arm that moves all the heads as a unit. The surface of a platter is logically divided into
circular tracks, which are subdivided into sectors. The set of tracks that are at one armposition
makes up a cylinder. There may be thousands of concentric cylinders in a disk drive, and each
track may contain hundreds of sectors. The storage capacity of common disk drives is measured
in gigabytes.
When the disk is in use, a drive motor spins it at high speed. Most drives rotate 60 to
250 times per second, specified in terms of rotations per minute (RPM). Common drives spin
at 5,400, 7,200, 10,000, and 15,000 RPM. Disk speed has two parts. The transfer rate is the rate
at which data flow between the drive and the computer. The positioning time, or random-access
time, consists of two parts: the time necessary to move the disk arm to the desired cylinder,
called the seek time, and the time necessary for the desired sector to rotate to the disk head,
called the rotational latency.
Typical disks can transfer several megabytes of data per second, and they have seek
times and rotational latencies of several milliseconds Other forms of removable disks include
CDs, DVDs, and Blu-ray discs as well as removable flash-memory devices known as flash drives
(which are a type of solid-state drive).
A disk drive is attached to a computer by a set of wires called an I/O bus. Several kinds
of buses are available, including advanced technology attachment (ATA), serial ATA (SATA),
eSATA, universal serial bus (USB), and fibre channel (FC). The data transfers on a bus are
carried out by special electronic processors called controllers. The host controller is the
controller at the computer end of the bus. A disk controller is built into each disk drive. To
perform a disk I/O operation, the computer places a command into the host controller, typically
using memory-mapped I/O ports.
Solid-State Disks
Sometimes old technologies are used in new ways as economics change or the technologies
evolve. An example is the growing importance of solid-state disks, or SSDs. Simply described,
an SSD is nonvolatile memory that is used like a hard drive. There are many variations of this
technology, from DRAM with a battery to allow it to maintain its state in a power failure through
flash-memory technologies like single-level cell (SLC) and multilevel cell (MLC) chips.
SSDs have the same characteristics as traditional hard disks but can be more reliable
because they have no moving parts and faster because they have no seek time or latency. In
addition, they consume less power. However, they are more expensive per megabyte than
traditional hard disks, have less capacity than the larger hard disks, and may have shorter life
spans than hard disks, so their uses are somewhat limited.
SSDs are also used in some laptop computers to make them smaller, faster, and more
energy-efficient. Because SSDs can be much faster than magnetic disk drives, standard bus
interfaces can cause a major limit on throughput.
Magnetic Tapes
Magnetic tape was used as an early secondary-storage medium. Although it is relatively
permanent and can hold large quantities of data, its access time is slow compared with that of
main memory and magnetic disk. In addition, random access to magnetic tape is about a
thousand times slower than random access to magnetic disk, so tapes are not very useful for
secondary storage.
Tapes are used mainly for backup, for storage of infrequently used information, and as
a medium for transferring information from one system to another
Tapes and their drivers are usually categorized by width, including 4, 8, and 19 millimeters and
1/4 and 1/2 inch. Some are named according to technology, such as LTO-5 and SDLT.
Disk Structure
Modern magnetic disk drives are addressed as large one-dimensional arrays of logical blocks,
where the logical block is the smallest unit of transfer. The size of a logical block is usually 512
bytes, although some disks can be low-level formatted to have a different logical block size,
such as 1,024 bytes.
The one-dimensional array of logical blocks is mapped onto the sectors of the disk
sequentially. Sector 0 is the first sector of the first track on the outermost cylinder. The mapping
proceeds in order through that track, then through the rest of the tracks in that cylinder, and
then through the rest of the cylinders from outermost to innermost.
Tracks in the outermost zone typically hold 40 percent more sectors than do tracks in
the innermost zone. The drive increases its rotation speed as the head moves from the outer to
the inner tracks to keep the same rate of data moving under the head. This method is used in
CD-ROM 10.3 Disk Attachment 471 and DVD-ROM drives. Alternatively, the disk rotation speed
can stay constant; in this case, the density of bits decreases from inner tracks to outer tracks to
keep the data rate constant. This method is used in hard disks and is known as constant angular
velocity (CAV).
The number of sectors per track has been increasing as disk technology improves, and
the outer zone of a disk usually has several hundred sectors per track. Similarly, the number of
cylinders per disk has been increasing; large disks have tens of thousands of cylinders.
Disk Attachment
Computers access disk storage in two ways. One way is via I/O ports (or host-attached storage);
this is common on small systems. The other way is via a remote host in a distributedfile system;
this is referred to as network-attached storage.
Host-Attached Storage
Host-attached storage is storage accessed through local I/O ports. These ports use several
technologies. The typical desktop PC uses an I/O bus architecture called IDE or ATA. This
architecture supports a maximum of two drives per I/O bus. A newer, similar protocol that has
simplified cabling is SATA.
High-end workstations and servers generally use more sophisticated I/O architectures such as
fibre channel (FC), a high-speed serial architecture that can operate over optical fiber or over
a four-conductor copper cable. It has two variants. One is a large switched fabric havinga 24-
bit address space. This variant is expected to dominate in the future and is the basis of storage-
area networks (SANs), because of the large address space and the switched nature of the
communication, multiple hosts and storage devices can attach to the fabric, allowing great
flexibility in I/O communication.
The other FC variant is an arbitrated loop (FC-AL) that can address 126 devices (drives
and controllers). A wide variety of storage devices are suitable for use as host-attached storage.
Among these are hard disk drives, RAID arrays, and CD, DVD, and tape drives.
Network-Attached Storage
➢ Network attached storage connects storage devices to computers using a remote
procedure call, RPC, interface, typically with something like NFS filesystem mounts. This
is convenient for allowing several computers in a group common access and naming
conventions for shared storage.
➢ NAS can be implemented using SCSI cabling, or ISCSI uses Internet protocols and
standard network connections, allowing long-distance remote access to shared files.
➢ NAS allows computers to easily share data storage, but tends to be less efficient than
standard host-attached storage.
The technique that operating system uses to determine the request which is to be satisfied
next is called disk scheduling.
Let's discuss some important terms related to disk scheduling.
Seek Time
Seek time is the time taken in locating the disk arm to a specified track where the read/write
request will be satisfied.
Rotational Latency
It is the time taken by the desired sector to rotate itself to the position from where it can
access the R/W heads.
Transfer Time
It is the time taken to transfer the data.
Disk Access Time
Disk access time is given as,
Disk Access Time = Rotational Latency + Seek Time + Transfer Time
Disk Response Time
It is the average of time spent by each request waiting for the IO operation.
Purpose of Disk Scheduling
The main purpose of disk scheduling algorithm is to select a disk request from the queue of IO
requests and decide the schedule when this request will be processed.
Goal of Disk Scheduling Algorithm
o Fairness
o High throughout
o Minimal traveling head time
Disk Scheduling Algorithms
The list of various disks scheduling algorithm is given below. Each algorithm is carrying some
advantages and disadvantages. The limitation of each algorithm leads to the evolution of a new
algorithm.
o FCFS scheduling algorithm
o SSTF (shortest seek time first) algorithm
o SCAN scheduling
o C-SCAN scheduling
o LOOK Scheduling
o C-LOOK scheduling
Scan Algorithm
It is also called as Elevator Algorithm. In this algorithm, the disk arm moves into a particular
direction till the end, satisfying all the requests coming in its path, and then it turns back and
moves in the reverse direction satisfying requests coming in its path.
It works in the way an elevator works, elevator moves in a direction completely till the last
floor of that direction and then turns back.
Example
Consider the following disk request sequence for a disk with 100 tracks
98, 137, 122, 183, 14, 133, 65, 78
Head pointer starting at 54 and moving in left direction. Find the number of head movements
in cylinders using SCAN scheduling.
C-SCAN algorithm
In C-SCAN algorithm, the arm of the disk moves in a particular direction servicing requests until
it reaches the last cylinder, then it jumps to the last cylinder of the opposite direction without
servicing any request then it turns back and start moving in that direction servicing the
remaining requests.
Example
Consider the following disk request sequence for a disk with 100 tracks
98, 137, 122, 183, 14, 133, 65, 78
Head pointer starting at 54 and moving in left direction. Find the number of head movements
in cylinders using C-SCAN scheduling.
Look Scheduling
It is like SCAN scheduling Algorithm to some extant except the difference that, in this scheduling
algorithm, the arm of the disk stops moving inwards (or outwards) when no more request in
that direction exists. This algorithm tries to overcome the overhead of SCAN algorithm which
forces disk arm to move in one direction till the end regardless of knowing if any request exists
in the direction or not.
Example
Consider the following disk request sequence for a disk with 100 tracks
98, 137, 122, 183, 14, 133, 65, 78
Head pointer starting at 54 and moving in left direction. Find the number of head movements
in cylinders using LOOK scheduling.
C Look Scheduling
C Look Algorithm is similar to C-SCAN algorithm to some extent. In this algorithm, the arm of
the disk moves outwards servicing requests until it reaches the highest request cylinder, then
it jumps to the lowest request cylinder without servicing any request then it again start moving
outwards servicing the remaining requests.
It is different from C SCAN algorithm in the sense that, C SCAN force the disk arm to move till
the last cylinder regardless of knowing whether any request is to be serviced on that cylinder
or not.
Example
Consider the following disk request sequence for a disk with 100 tracks
98, 137, 122, 183, 14, 133, 65, 78
Head pointer starting at 54 and moving in left direction. Find the number of head movements
in cylinders using C LOOK scheduling.
Virtual memory is a combination of RAM and disk space that running processes can use.
Swap space is the portion of virtual memory that is on the hard disk, used when RAM is
full.
Swap space can be useful to computer in various ways:
• It can be used as a single contiguous memory which reduces i/o operations to read or
write a file.
• Applications which are not used or are used less can be kept in swap file.
• Having sufficient swap file helps the system keep some physical memory free all the time.
• The space in physical memory which has been freed due to swap space can be used by OS
for some other important tasks.
In operating systems such as Windows, Linux, etc systems provide a certain amount of swap
space by default which can be changed by users according to their needs. If you don’t want to
use virtual memory you can easily disable it all together but in case if you run out of memory
then kernel will kill some of the processes in order to create a sufficient amount of space in
physical memory.
So it totally depends upon user whether he wants to use swap space or not.Alternatively,
swap space can be created in a separate raw partition. No file system or directory structure is
placed in this space. Rather, a separate swap-space storage manager is used to allocate and
deallocate the blocks from the raw partition. This manager uses algorithms optimized for speed
rather than for storage efficiency, because swap space is accessed much more frequently than
file systems (when it is used).
Stable-Storage Implementation
By definition, information residing in stable storage is never lost. To implement such storage,
we need to replicate the required information on multiple storage devices (usually disks) with
independent failure modes. We also need to coordinate the writing of updates in a way that
guarantees that a failure during an update will not leave all the copies in a damaged state and
that, when we are recovering from a failure, we can force all copies to a consistent and correct
value, even if another failure occurs during the recovery. A disk write results in one of three
outcomes:
1. Successful completion. The data were written correctly on disk.
2. Partial failure. A failure occurred in the midst of transfer, so only some of the sectors were
written with the new data, and the sector being written during the failure may have been
corrupted.
3. Total failure. The failure occurred before the disk write started, so the previous data values
on the disk remain intact.
Whenever a failure occurs during writing of a block, the system needs to detect it and
invoke a recovery procedure to restore the block to a consistent state. To do that, the system
must maintain two physical blocks for each logical block. An output operation is executed as
follows:
1. Write the information onto the first physical block.
2. When the first write completes successfully, write the same information onto the second
physical block.
3. Declare the operation complete only after the second write completes successfully.
During recovery from a failure, each pair of physical blocks is examined. If both are the same
and no detectable error exists, then no further action is necessary. If one block contains a
detectable error then we replace its contents with the value of the other block. If neither block
contains a detectable error, but the blocks differ in content, then we replace the content of the
first block with that of the second. This recovery procedure ensures that a write to stable
storage either succeeds completely or results in no change.
Very durable and reliable Read-only disks, such ad CD-ROM and DVD, come
from thefactory with the data pre-recorded
Tapes
Compared to a disk, a tape is less expensive and holds more data, but random
access ismuch slower.
Tape is an economical medium for purposes that do not require fast random
access, e.g.,backup copies of disk data, holding huge volumes of data.
Large tape installations typically use robotic tape changers that move tapes
between tapedrives and storage slots in a tape library
stacker – library that holds a few tapes
silo – library that holds thousands of tapes
A disk-resident file can be archived to tape for low cost storage; the computer
can stage itback into disk storage for active use.
I/O control
Devices
I/O Control: consists of device drivers and interrupt handlers to transfer information
between the main memory and the disk system. The device driver 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 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 (Eg. Drive 1, cylinder 73, track2, sector 10).
The File Organization Module knows about files and their logical blocks and physical
blocks. By knowing the type of file allocation used and the location of the file, file
organization module can translate logical block address to physical 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 all file system structure except the actual data (contents
of file). It maintains file structure via file control blocks. A file control block (inode in Unix
file systems) contains information about the file, ownership, permissions, location of the
file contents.
Overview:
A Boot Control Block (per volume) can contain information needed by the system to
boot an OS from that volume. If the disk does not contain an OS, this block can be empty.
A Volume Control Block (per volume) contains volume (or partition) details, such as
number of blocks in the partition, size of the blocks, a free block, count and free block
pointers, free FCB count, FCB pointers.
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.
Free-Space Management
File system maintains free-space list to track available blocks/clusters Linked list (free
list)
o Cannot get contiguous space easily
o No waste of space
o No need to traverse the entire list
1. Bitmap or Bit vector – 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.
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.
Grouping
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
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
1. Linear List
• The simplest method of implementing a directory is to use a linear list of file names
with pointer to the data blocks.
• A linear list of directory entries requires a linear search to find a particular entry.
• This method is simple to program but time- consuming to execute. To create a new
file, we must first search the but time – consuming to execute.
• The real disadvantage of a linear list of directory entries is the linear search to find a
file.
2. Hash Table
• In this method, a linear list stores the directory entries, but a hash data structure is
also used.
• The hash table takes a value computed from the file name and returns a pointer to the
file name in the linear list.
• Therefore, it can greatly decrease the directory search time.
• Insertion and deleting are also fairly straight forward, although some provision must
be made for collisions – situation where two file names hash to the same location.
• The major difficulties with a hash table are its generally fixed size and the dependence
of the hash function on that size.
ALLOCATION METHODS
An allocation method deals with how to allocate space to the files so that disk space is
utilized effectively and files can be accessed quickly.
There are there major methods of allocating disk space:
1. Contiguous Allocation
2. Linked Allocation
3. Indexed Allocation
1. Contiguous Allocation
The contiguous – allocation method requires each file to occupy a set of contiguous
blocks on the disk.
Contiguous allocation of a file is defined by the disk address and length (in block units)
of the first block. If the file is n blocks long and starts at location b, then itoccupies
blocks b, b+1, b+2,….,b+n-1.
The directory entry for each file indicates the address of the starting block and the
length allocated for this file.
Disadvantages:
1. Finding space for a new file.
It suffers from the problem of external fragmentation. Storage is fragmented into a
number of holes, no one of which is large enough to store the needed data.
2. Determining how much space is needed for a file.
When the file is created, the total amount of space it will need must be specified. It is
not possible for all files.
Even if the total amount of space needed for a file is known in advance pre-allocation
may be inefficient.
A file that grows slowly over a long period (months or years) must be allocated
enough space for its final size therefore has an internal fragmentation.
Disadvantages:
1. Used effectively only for sequential access files.
To find the ith block of a file, we must start at the beginning of that file, and follow the
pointers until we get to the ith block. It is inefficient to support a direct- access capability
for linked allocation files.
2. Space required for the pointers
If a pointer requires 4 bytes out of a 512-byte block, then 0.78 percent of the disk is being
used for pointers, rather than for information. Solution to this problem is tocollect blocks
into multiples, called clusters, and to allocate the clusters rather than blocks.
3. Reliability
Since the files are linked together by pointers scattered all over the disk hardware failure
might result in picking up the wrong pointer. This error could result in linking into the
free- space list or into another file.
File Allocation Table(FAT)
An important variation on the linked allocation method is the use of a file allocation
table(FAT).
This simple but efficient method of disk- space allocation is used by the MS-DOS and
OS/2 operating systems.
A section of disk at beginning of each partition is set aside to contain the table.
The table has entry for each disk block, and is indexed by block number.
The FAT is much as is a linked list.
The directory entry contains the starting block number of the file.
The table entry indexed by that block number contains the block number of the next
block in the file.
This chain continues until the last block which has a special end – of – file value as the
table entry.
Unused blocks are indicated by a 0 table value.
Allocating a new block file is a simple matter of finding the first 0 – valued table entry,
and replacing the previous end of file value with the address of the new block.
Example the FAT structure for a file consisting of disk blocks 217,618, and 339.
3. Indexed Allocation
Linked allocation solves the external – fragmentation and size- declaration problems
of contiguous allocation.
Linked allocation cannot support efficient direct access, since the pointers to the
blocks are scattered.
Indexed allocation solves this problem by bringing all the pointers together into one
location: the index block.
Each file has its own index block, which is an array of disk – block addresses.
The ith entry in the index block points to the ith block of the file.
The directory contains the address of the index block .
To read the ith block, we use the pointer in the ith index – block entry to find and read
the desired block this scheme is similar to the paging scheme.
Disadvantages
1.Pointer Overhead
Indexed allocation suffers from wasted space. The pointer over head of the index block
is generally greater than the pointer over head of linked allocation.
2. Size of Index block
If the index block is too small, however, it will not be able to hold enough pointers for a
large file.
Linked Scheme: An index block is normally one disk block. Thus, it can be read and
written directly by itself. To allow for large files, we may link together several index
blocks.
Multilevel index: A variant of the linked representation is to use a first level indexblock
to point to a set of second – level index blocks.
Combined scheme:
Another alternative, used in the UFS, is to keep the first, say, 15 pointers of the index
block in the file’s inode.
The first 12 of these pointers point to direct blocks; that is for small ( no more than 12
blocks) files do not need a separate index block
The next pointer is the address of a single indirect block.
The single indirect block is an index block, containing not data, but rather the
addresses of blocks that do contain data.
Then there is a double indirect block pointer, which contains the address of a block that
contains pointers to the actual data blocks. The last pointer would contain pointers to the
actual data blocks.
The last pointer would contain the address of a triple indirect block.