Deadlock Memory Management
Deadlock Memory Management
1. Requests a resource
2. Use the resource
3. Releases the resource
Deadlock: A deadlock is a situation where a set of processes are blocked because each process is holding a
resource and waiting for another resource acquired by some other process.
Consider an example when two trains are coming toward each other on the same track and there is only one
track, none of the trains can move once they are in front of each other. A similar situation occurs in operating
systems when there are two or more processes that hold some resources and wait for resources held by
others.
For example, in the below diagram, Process 1 is holding Resource 1 and waiting for resource 2 which is
acquired by process 2, and process 2 is waiting for resource 1.
If there is a cycle in the Resource Allocation Graph and each resource in the cycle provides only one instance,
then the processes will be in a deadlock.
Deadlock Prevention
Deadlock prevention algorithms ensure that at least one of the necessary conditions (Mutual exclusion, hold
and wait, no pre-emption and circular wait) does not hold. However, most prevention algorithms have poor
resource utilization and hence result in reduced throughputs.
• Mutual Exclusion
Not always possible to prevent deadlock by preventing mutual exclusion (making all resources shareable) as
certain resources are cannot be shared safely.
• Hold and Wait: There are two approaches, but both have their disadvantages -
1. A resource can get all required resources before it starts execution. This will avoid deadlock but will
result in reduced throughputs as resources are held by processes even when they are not needed.
They could have been used by other processes during this time.
2. The second approach is to request a resource only when it is not holding any other resource. This may
result in starvation as all required resources might not be available freely always.
• No pre-emption: There are two approaches
1. If a process requests a resource that is held by another waiting resource, then the resource may be
pre-empted from the other waiting resource. In the second approach, if a process requests a resource
that is not readily available, all other resources that it holds are pre-empted.
2. The challenge here is that the resources can be pre-empted only if we can save the current state can
be saved and processes could be restarted later from the saved state.
• Circular wait
To avoid the circular wait, resources may be ordered, and we can ensure that each process can request
resources only in increasing order of these numbers. The algorithm may itself increase complexity and may
also lead to poor resource utilization.
Deadlock Avoidance
This requires that the system has some information available upfront. Each process declares the maximum
number of resources of each type which it may need. Dynamically examine the resource-allocation state to
ensure that there can never be a circular-wait condition.
The system's resource-allocation state is defined by the number of available and allocated resources, and the
maximum possible demands of the processes. When a process requests an available resource, the system
must decide if immediate allocation leaves the system in a safe state.
The system is in a safe state if there exist a safe sequence of all processes:
Sequence < P1, P2, ..Pn> is safe for the current allocation state if, for each Pi, the resources which Pi can
request can be satisfied by
• The currently available resources
• The resources held by all of the Pj's, where j<i.
If the system is in a safe state, there can be no deadlock. If the system is in an unsafe state, there is the
possibility of deadlock.
Banker's Algorithm
• A classic deadlock avoidance algorithm
• More general than resource-allocation graph algorithm (handles multiple instances of each resource
type), but Is less efficient
We call Banker's algorithm when a request for R is made. Let n be the number of processes in the system, and
m be the number of resource types.
Following are the data structure used in Banker’s Algorithm
• Available[m]: the number of units of R currently unallocated (e.g., available [3] = 2)
• Max[n][m]: describes the maximum demands of each process (e.g., max [3][1] = 2)
• Allocation[n][m]: describes the current allocation status (e.g., allocation [5][1] = 3)
• Need[n][m]: describes the remaining possible need (i.e., need[i][j] = max[i][j] - allocation[i][j])
Resource-request algorithm:
Request[n] [m]: describes the current outstanding requests of all processes (e.g., request [2][1] = 3)
1. If request [i] [j] <= need [i] [j], go to step 2; otherwise, raise an error condition.
2. If request [i] [j] > available [j], then the process must wait.
3. If finish[i] == true for all i, then the system is in a safe state, otherwise unsafe.
Example: consider a system with 5 processes (P0 ... P4) and 3 resources types [A (10) B (5) C (7)]
Resource-allocation state at time t0:
Process Allocation Max Need Available
A B C A B C A B C A B C
P0 0 1 0 7 5 3 7 4 3 3 3 2
P1 2 0 0 3 2 2 1 2 2 10 5 7-→Res
P2 3 0 2 9 0 2 6 0 0
P3 2 1 1 2 2 2 0 1 1
P4 0 0 2 4 3 3 4 3 1
Table 3.1: Numerical Example
Above the given table is in a safe state and the sequence for execution is:
< P1, P3, P4, P2, P0 >
Now suppose, P1 requests an additional instance of A and 2 more instances of type C
Request [1] = (1, 0, 2)
1. Check if request [1] <= need[i] (yes)
2. Check if request [1] <= available[i] (yes)
3. Do pretend updates to the state
Process Allocation Max Need Available
A B C A B C A B C A B C
P0 0 1 0 7 5 3 7 4 3 3 3 2
P1 3 0 2 3 2 2 0 2 0
P2 3 0 2 9 0 2 6 0 0
P3 2 1 1 2 2 2 0 1 1
P4 0 0 2 4 3 3 4 3 1
Table 3.2: After P1 Request
Above the given table is in a safe state and the sequence for execution is:
<P1, P3, P4, P0, P2>
Hence, we immediately grant the request.
Deadlock Detection
• Requires an algorithm that examines the state of the system to determine whether a deadlock has
occurred
• Requires overhead
• Run-time cost of maintaining necessary information and executing the detection algorithm
• Potential losses inherent in recovering from deadlock
A single instance of each resource type for wait-graph
• Pi → pj = pi>rq and rq → pj
• Detect cycle: o(n²)
• Overhead: maintain the graph + invoke the algorithm
Resource-allocations graphs for deadlock detection
Figure 3.7: Resource-Allocations and Wait for Graphs for Deadlock Detection
To detect the deadlock OS uses an algorithm similar to Banker's, which simply investigates every possible
allocation sequence for the processes which remain to be completed.
Following data structure is used
• Available[m]
• Allocation[n][m]
• Request[n][m]
Algorithm:
1. Let work be an integer array of length m, initialized to available. Let finish be a Boolean array of length
n. For all i,
If allocation[i]! = 0, then finish[i] = false;
Otherwise finish[i] = true.
2. Find i such that both
• Finish[i] == false // Pi is currently not involved in a deadlock
• Request[i] <= work
If no such i exists, go to step 4
3. Reclaim the resources of process Piwork = work + allocation[i]; finish[i] = true; Go to step 2
4. If finish [i] == false for some i, Then the system is in a deadlocked state.
Moreover, if finish[i] == false, then process Pi is deadlocked.
Example: consider a system with 5 processes (P0 ... P4) and 3 resources types (A (7) B (2) C (6))
Resource-allocation state at time t0:
Process Allocation Request Available
A B C A B C A B C
P0 0 1 0 0 0 0 0 0 0
P1 2 0 0 2 0 2
P2 3 0 3 0 0 0
P3 2 1 1 1 0 0
P4 0 0 2 0 0 2
Table 3.3: Resource-allocation state
Above the given table is in a safe state and the sequence for execution is:
< P0, P2, P3, P1, P4 >
We can reclaim the resources held by P0, the number of available resources is insufficient to fulfil the requests
of the other processes.
Thus, a deadlock exists, consisting of processes P1, P2, P3, and P4.
Deadlock Recovery:
Deadlock recovery performs when a deadlock is detected. When deadlock detected, then our system stops
working, and after the recovery of the deadlock, our system start working again. Therefore, after the
detection of deadlock, a method must require to recover that deadlock to run the system again. The method is
called as deadlock recovery.
Deadlock Recovery through Pre-emption: The ability to take a resource away from a process, have another
process use it, and then give it back without the process noticing. It is highly dependent on the nature of the
resource. Deadlock recovery through pre-emption is too difficult or sometime impossible.
Deadlock Recovery through Rollback: In this case of deadlock recovery through rollback, whenever a deadlock
is detected, it is easy to see which resources are needed. To do the recovery of deadlock, a process that owns
a needed resource is rolled back to a point in time before it acquired some other resource just by starting one
of its earlier checkpoints.
Deadlock Recovery through Killing Processes: This method of deadlock recovery through killing processes is
the simplest way of deadlock recovery. Sometime it is best to kill a process that can be return from the
beginning with no ill effects.
1 Symbolic addresses
The addresses used in a source code. The variable names, constants, and instruction labels are the
basic elements of the symbolic address space.
2 Relative addresses
At the time of compilation, a compiler converts symbolic addresses into relative addresses.
3 Physical addresses
The loader generates these addresses at the time when a program is loaded into the main memory.
Table 3.5: Memory addresses
Address binding
• Memory consists of a large array of words or arrays, each of which has an address associated with it.
Now the work of the CPU is to fetch instructions from the memory-based program counter. Now
further these instructions may cause loading or store to a specific memory address.
• Address binding is the process of mapping from one address space to another address space. The
logical address is the address generated by the CPU during execution whereas Physical Address refers
to a location in a memory unit (the one that is loaded into memory).
• Note that the user deals with only a logical address (Virtual address). The logical address undergoes
translation by the MMU or address translation unit. The output of this process is the appropriate
physical address or the location of code/data in RAM.
Virtual and physical addresses are the same in compile-time and load-time address-binding schemes. Virtual
and physical addresses differ in the execution-time address-binding scheme.
To protect the operating system code and data by the user processes as well as protect user processes from
one another using relocation register and limit register. This is depicted in the figure below:
Memory management Techniques: In an operating system, the following are four common memory
management techniques.
1. Single contiguous allocation: Simplest allocation method used by MS-DOS. All memory (except some
reserved for OS) is available to a process.
2. Partitioned allocation: Memory is divided into different blocks
3. Paged memory management: Memory is divided into fixed-sized units called page frames, used in a
virtual memory environment.
4. Segmented memory management: Memory is divided into different segments (a segment is a logical
grouping of process' data or code) in this management, allocated memory doesn’t have to be
contiguous.
Memory Allocation:
Single Partition Allocation: In this memory allocation method, the operating system resides in the low
memory, and the remaining memory is treated as a single partition. This single partition is available for user -
space, only one job can be loaded in this user space.
Fixed-equal Multiple Partitions: In this memory management, the operating system occupies the low memory
and the rest of the main memory is available for user-space. The user space is divided into fixed partitions. The
partition sizes are depending on the operating system.
Fixed-variable Partitions: In this memory management, the user space of the main memory is divided into the
number of partitions, but the partition sizes are different lengths. The operating system keeps a table
indicating which partitions of memory are available and which are occupied.
Dynamic Partitions: To eliminate some of the problems with fixed partitions, an approach known as Dynamic
Partitions. In this method, partitions are created dynamically, so that each process is loaded into the partition
of the same size at that 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.
Paging
Paging is a memory management scheme that eliminates the need for contiguous allocation of physical
memory. This scheme permits the physical address space of a process to be non – contiguous.
● Logical Address or Virtual Address (represented in bits): An address generated by the CPU
● Logical Address Space or Virtual Address Space (represented in words or bytes): The set of all logical
addresses generated by a program
● Physical Address (represented in bits): An address available on the memory unit
● Physical Address Space (represented in words or bytes): The set of all physical addresses corresponding
to the logical addresses
Example:
● If Logical Address = 31 bit, then Logical Address Space = 231 words = 2 G words (1 G = 230)
● If Logical Address Space = 128 M words = 27 * 220 words, then Logical Address = log2 227 = 27 bits
● If Physical Address = 22 bit, then Physical Address Space = 222 words = 4 M words (1 M = 220)
● If Physical Address Space = 16 M words = 24 * 220 words, then Physical Address = log2 224 = 24 bits
The mapping from virtual to physical address is done by the memory management unit (MMU) which is a
hardware device and this mapping is known as the paging technique.
● The Physical Address Space is conceptually divided into a number of fixed-size blocks, called frames.
● The Logical Address Space is also split into fixed-size blocks, called pages.
● Page Size = Frame Size
Page Fault
• A page fault occurs when a program attempts to access a block of memory that is not stored in the
physical memory or RAM.
• The fault notifies the operating system that it must locate the data in virtual memory, and then
transfer it from the storage device, such as an HDD or SSD, to the system RAM. Though the term "page
fault" sounds like an error, page faults are common and are part of the normal way computers handle
virtual memory.
• In programming terms, a page fault generates an exception, which notifies the operating system that it
must retrieve the memory blocks or "pages" from virtual memory for the program to continue. Once
the data is moved into physical memory, the program continues as normal.
• This process takes place in the background and usually goes unnoticed by the user.
So when a page fault occurs then the following sequence of events happens:
Figure 3.14: Page fault
Segmentation
• Segmentation is a memory management technique in which each job is divided into several segments
of different sizes; each segment is a different logical address space of the program.
• When a process is to be executed, its corresponding segmentation is 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 whereas 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 every process and a list of free memory
blocks along with segment numbers, their size and corresponding memory locations in the 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.
The percentage of times that the page number of interest is found in the TLB is called the hit ratio. An 80-per
cent hit ratio, for example, means that we find the desired page number in the TLB 80 percent of the time. If it
takes 100 nanoseconds to access memory, then mapped-memory access takes 100 nanoseconds when the
page number is in the TLB. If we fail to find the page number in the TLB then we must first access memory for
the page table and frame number (100 nanoseconds) and then access the desired byte in memory (100
nanoseconds), for a total of 200 nanoseconds. (We are assuming that a page-table lookup takes only one
memory access)
To find the effective memory-access time, we weight the case by its probability: effective access time = 0.80 ×
100 + 0.20 × 200 = 120 nanoseconds
Time efficiency of using cache memories results from the locality of access to data that is observed during
program execution.
Time locality: Time locality consists of a tendency to use many times the same instructions and data in
programs during neighbouring time intervals.
Space locality: Space locality is a tendency to store instructions and data used in a program in short distances
of time under neighbouring addresses in the main memory.
• Due to these localities, the information loaded to the cache memory is used several times and the
execution time of programs is much reduced.
• The cache can be implemented as a multi-level memory. Contemporary computers usually have two
levels of caches. In older computer models, a cache memory was installed outside a processor (in
separate integrated circuits than the processor itself).
• The access to it was organized over the processor external system bus. In today's computers, the first
level of the cache memory is installed in the same integrated circuit as the processor.
• It significantly speeds up the processor's cooperation with the cache. Some microprocessors have the
second level of cache memory placed also in the processor's integrated circuit.
• The volume of the first-level cache memory is from several thousand to several tens of thousands of
bytes. The second-level cache memory has a volume of several hundred thousand bytes.
• Cache memory is maintained by a special processor subsystem called cache controller.
• Write through, the new cache contents are written down to the main memory immediately after the
write to the cache memory,
• Write back, the new cache contents are not written down to the main memory immediately after the
change, but only when the given block of data is replaced by a new block fetched from the main
memory or an upper-level cache. After a data write to the cache, only state bits are changed in the
modified block, indicating that the block has been modified (a dirty block).
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.
Allocation of Frames
Frame allocation algorithms are used if OS uses multiple processes; it helps decide how many frames to
allocate to each process.
There are various constraints to the strategies for the allocation of frames:
● OS cannot allocate more than the total number of available frames.
● At least a minimum number of frames should be allocated to each process. This constraint is supported
by two reasons. The first reason is, as less number of frames are allocated, there is an increase in the
page fault ratio, decreasing the performance of the execution of the process. Secondly, there should be
enough frames to hold all the different pages that any single instruction can reference.
Frame allocation algorithms: The two algorithms commonly used to allocate frames to a process are
1. Equal allocation: In a system with x frames and y processes, each process gets equal number of frames,
i.e. x/y. For instance, if the system has 48 frames and 9 processes, each process will get 5 frames. The
three frames which are not allocated to any process can be used as a free-frame buffer pool.
2. Proportional allocation: Frames are allocated to each process according to the process size. For a
process pi of size si, the number of allocated frames is ai = (si/S)*m, where S is the sum of the sizes of
all the processes and m is the number of frames in the system. For instance, in a system with 62
frames, if there is a process of 10KB and another process of 127KB, then the first process will be
allocated (10/137)*62 = 4 frames and the other process will get (127/137)*62 = 57 frames.
● Global: When a process needs a page which is not in the memory, it can bring in the new page and
allocate it a frame from the set of all frames, even if that frame is currently allocated to some other
process; that is, one process can take a frame from another.
● Local: When a process needs a page which is not in the memory, it can bring in the new page and
allocate it a frame from its own set of allocated frames only.
Thrashing
Whenever a page fault happens, operating system will try to fetch that page from secondary memory and try
to swap it with one of the page in RAM. This is called swapping.
If this page fault and then swapping happening very frequently at higher rate, then operating system has to
spend more time to swap these pages. This state is called thrashing. Because of this, CPU utilization is going to
be reduced.
Causes of Thrashing
● Thrashing affects the performance of execution in the Operating system. Also, thrashing results in
severe performance problems in the Operating system.
● When the utilization of CPU is low, then the process scheduling mechanism tries to load many
processes into the memory at the same time due to which degree of multiprogramming can be
increased. Now in this situation, there are more processes in the memory as compared to the available
number of frames in the memory. Allocation of the limited amount of frames to each process.
● Whenever any process with high priority arrives in the memory and if the frame is not freely available
at that time then the other process that has occupied the frame is residing in the frame will move to
secondary storage and after that this free frame will be allocated to higher priority process.