OS Module3 (1)
OS Module3 (1)
Process Synchronization
5.1Background
Since processes frequently needs to communicate with other processes therefore, there is a
need for a well- structured communication, without using interrupts, among processes.
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 ensure only one process at a time can be manipulating the
variable or data. To make such a guarantee processes need to be synchronized in some way
Consider a system consisting of n processes {P0, P1, ..., Pn−1}. Each process has a segment
of code, called a critical section, in which the process may be changing common variables,
updating a table, writing a file, and so on. when one process is executing in its critical
section, no other process is allowed to execute in its critical section. The critical-section
problem is to design a protocol that the processes can use to cooperate. Each process must
request permission to enter its critical section. 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
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
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:
Preemptive kernels: A preemptive kernel allows a process to be preempted while it
is running in kernel mode.
Nonpreemptive kernels.. A nonpreemptive kernel does not allow a process running
in kernel mode to be preempted; a kernel-mode process will run until it exits kernel
mode, blocks, or voluntarily yields control of the CPU.
5.3 Peterson’s Solution
It proves that
1. Mutual exclusion is preserved
2. Progress requirement is satisfied
3. Bounded-waiting requirement is met
Using test and set() instruction, mutual exclusion can be implemented by declaring a
boolean variable lock, initialized to false. The structure of process Pi is shown in
Figure:
Test and Set() instruction & Swap() Instruction do not satisfy the bounded-waiting
requirement.
5.5 Semaphores
The hardware-based solutions to the critical-section problem are complicated as well as
generally inaccessible to application programmers. So operating-systems designers build
software tools to solve the critical-section problem, and this synchronization tool called as
Semaphore.
Semaphore S is an integer variable
Two standard operations modify S: wait() and
signal() Originally called P() and V()
Can only be accessed via two indivisible (atomic) operations
Must guarantee that no two processes can execute wait () and signal () on the same
semaphore at the same time.
Usage:
Semaphore classified into:
Counting semaphore: Value can range over an unrestricted domain
Binary semaphore(Mutex locks): Value can range only between from 0 & 1. It
provides mutual exclusion.
Implementation:
The disadvantage of the semaphore is busy waiting i.e While a process is in critical
section, any other process that tries to enter its critical section must loop continuously
in the entry code. Busy waiting wastes CPU cycles that some other process might be
able to use productively. This type of semaphore is also called a spin lock because the
process spins while waiting for the lock.
Solution for Busy Waiting problem:
Modify the definition of the wait() and signal()operations as follows: When a process
executes the wait() operation and finds that the semaphore value is not positive, it must wait.
Rather than engaging in busy waiting, the process can block itself. The block operation places
a process into a waiting queue associated with the semaphore, and the state of the process is
switched to the waiting state. Then control is transferred to the CPU scheduler, which selects
another process to execute.
A process that is blocked, waiting on a semaphore S, should be restarted when some other
process executes a signal() operation. The process is restarted by a wakeup() operation, which
changes the process from the waiting state to the ready state. The process is then placed in the
ready queue.
To implement semaphores under this definition, define a semaphore as follows:
typedef struct {
int value;
struct process *list;
} semaphore;
Each semaphore has an integer value and a list of processes list. When a process must wait on
a semaphore, it is added to the list of processes. A signal() operation removes one process
from the list of waiting processes and awakens that process. Now, the wait() semaphore
operation can be defined as:
wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S-
>list; block();
}
}
and the signal() semaphore operation can be defined as
signal(semaphore *S) {
S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}
The block() operation suspends the process that invokes it. The wakeup(P) operation resumes
the execution of a blocked process P.
Consider below example: a system consisting of two processes, P0 and P1, each accessing
two semaphores, S and Q, set to the value 1:
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.
Another problem related to deadlocks is indefinite blocking or starvation.
Only one single writer can access the shared data at the same time
Several variations of how readers and writers are treated – all involve priorities.
First variation – no reader kept waiting unless writer has permission to use
shared object
Second variation- Once writer is ready, it performs asap.
Shared Data
Data set
Consider five philosophers who spend their lives thinking and eating. The
philosophers share a circular table surrounded by five chairs, each belonging to one
philosopher. In the center of the table is a bowl of rice, and the table is laid with five
single chopsticks.
philosopher tries to grab a chopstick by executing a wait() operation on that semaphore. She
releases her chopsticks by executing the signal() operation on the appropriate semaphores.
Thus, the shared data are
semaphore chopstick[5];
where all the elements of chopstick are initialized to 1. The structure of philosopher i is
shown in Figure
5.8 Monitors
Incorrect use of semaphore operations:
Suppose that a process interchanges the order in which the wait() and signal()
operations on the semaphore mutex are executed, resulting in the following execution:
signal(mutex);
...
critical section
...
wait(mutex);
Suppose that a process replaces signal(mutex) with wait(mutex). That is, it executes
wait(mutex);
...
critical section
...
wait(mutex);
condition x, y;
The only operations that can be invoked on a condition variable are wait() and signal(). The
operation
x.wait();
means that the process invoking this operation is suspended until another process invokes
x.signal();
The x.signal() operation resumes exactly one suspended process. If no process is suspended,
then the signal() operation has no effect; that is, the state of x is the same as if the operation
had never been executed. Contrast this operation with the signal() operation associated with
semaphores, which always affects the state of the semaphore.
For each monitor, a semaphore mutex (initialized to 1) is provided. A process must execute
wait(mutex) before entering the monitor and must execute signal(mutex) after leaving the
monitor.
Since a signaling process must wait until the resumed process either leaves or waits, an
additional semaphore, next, is introduced, initialized to 0. The signaling processes can use
next to suspend themselves. An integer variable next_count is also provided to count the
number of processes suspended on next. Thus, each external function F is replaced by
Page 18
Module 2 Chap-2: Process Synchronization
where c is an integer expression that is evaluated when the wait() operation is executed. The
value of c, which is called a priority number, is then stored with the name of the process
that is suspended. When x.signal() is executed, the process with the smallest priority number
is resumed next.
Page 19
Module 2 Chap-2: Process Synchronization
The ResourceAllocator monitor shown in the above Figure, which controls the allocation of
a single resource among competing processes.
A process that needs to access the resource in question must observe the following sequence:
R.acquire(t);
...
access the resource;
...
R.release();
where R is an instance of type ResourceAllocator.
The monitor concept cannot guarantee that the preceding access sequence will be observed.
In particular, the following problems can occur:
A process might access a resource without first gaining access permission to the
resource.
A process might never release a resource once it has been granted access to the
resource.
A process might attempt to release a resource that it never requested.
A process might request the same resource twice (without first releasing the resource).
Page 20
Module 2 Chap-2: Process Synchronization
Page 21
Module 2 Chap-2: Process Synchronization
Page 22
Module 2 Chap-2: Process Synchronization
MODULE 3: DEADLOCKS
MEMORY MANAGEMENT
3.1 Deadlocks
3.2 System Model
3.3 Deadlock Characterization
3.3.1 Necessary Conditions
3.3.2 Resource Allocation Graph
3.4 Methods for Handling Deadlocks
3.5 Deadlock Prevention
3.5.1 Mutual Exclusion
3.5.2 Hold and Wait
3.5.3 No Preemption
3.5.4 Circular Wait
3.6 Deadlock Avoidance
3.6.1 Safe State
3.6.2 Resource Allocation Graph Algorithm
3.6.3 Banker's Algorithm
3.6.3.1 Safety Algorithm
3.6.3.2 Resource Request Algorithm
3.6 3.3 An Illustrative Example
3.7 Deadlock Detection
3.7.1 Single Instance of Each Resource Type
3.7.2 Several Instances of a Resource Type
3.7.3 Detection Algorithm Usage
3.8 Recovery from Deadlock
3.8.1 Process Termination
3.8.2 Resource Preemption
3.9 Main Memory
3.9.1 Basic Hardware
Dept. of CSE(DS), SJBIT Page 28
Module 2 Chap-2: Process Synchronization
3.9.2 Address Binding
3.9.3 Logical versus Physical Address Space
3.9.4 Dynamic Loading
3.9.5 Dynamic Linking and Shared Libraries
3.10 Swapping
3.11 Contiguous Memory Allocation
3.11.1 Memory Mapping & Protection
3.11.2 Memory Allocation
3.11.3 Fragmentation
3.12 Segmentation
3.13 Paging
3.13.1 Basic Method
3.13.2 Hardware Support for Paging
3.13.3 Protection
3.13.4 Shared Pages
3.14 Structure of
the Page
Table
3.14.1 Hierarchical
Pag
ing
3.14.2 Hashed Page
Tabl
es
3.14.3 Inverted Page
Table
s
3.15 Segmentation
3.15.1 Basic Method
3.15.2 Hardware Support
3-1
MODULE 3: DEADLOCKS
3.1 Deadlocks
• Deadlock is a situation where a set of processes are blocked because each process is
→ holding a resource and
→ waiting for another resource held by some other process.
• Real life example:
When 2 trains are coming toward each other on same track and there is only one track, none of the
trains can move once they are in front of each other.
• Similar situation occurs in operating systems when there are two or more processes hold some
resources and wait for resources held by other(s).
• Here is an example of a situation where deadlock can occur (Figure 3.1).
(a) Resource allocation Graph (b) With a deadlock (c) with cycle but no deadlock
Figure 3.3 Resource allocation graphs
Conclusion:
1) If a graph contains no cycles, then the system is not deadlocked.
2) If the graph contains a cycle then a deadlock may exist.
Therefore, a cycle means deadlock is possible, but not necessarily present.
3.5 Deadlock-Prevention
• Deadlocks can be eliminated by preventing at least one of the four required conditions:
1) Mutual exclusion
2) Hold-and-wait
3) No preemption
4) Circular-wait.
3.5.1 Mutual Exclusion
• This condition must hold for non-sharable resources.
• For example:
A printer cannot be simultaneously shared by several processes.
• On the other hand, shared resources do not lead to deadlocks.
• For example:
Simultaneous access can be granted for read-only file.
• A process never waits for accessing a sharable resource.
• In general, we cannot prevent deadlocks by denying the mutual-exclusion condition because some
resources are non-sharable by default.
}
• These 2 protocols may be applicable for resources whose states are easily saved and restored, such as
registers and memory.
• But, these 2 protocols are generally not applicable to other devices such as printers and tape drives.
3.5.4 Circular-Wait
• Deadlock can be prevented by using the following 2 protocol:
Protocol-1
Assign numbers all resources.
Require the processes to request resources only in increasing/decreasing order.
Protocol-2
Require that whenever a process requests a resource, it has released resources with a lower
number.
• One big challenge in this scheme is determining the relative ordering of the different resources.
• Problem:
The resource-allocation graph algorithm is not applicable when there are multiple instances for
each resource.
• Solution:
Use banker's algorithm.
Step 1:
Let Work and Finish be two vectors of length m and n respectively.
Initialize:
Work = Available
Finish[i] = false for i=1,2,3,…….n
Step 2:
Find an index(i) such that both
a) Finish[i] = false
b) Need i <= Work.
If no such i exist, then go to step 4
Step 3:
Set:
Work = Work + Allocation(i)
Finish[i] = true
Go to step 2
Step 4:
If Finish[i] = true for all i, then the system is in safe state.
Step 1:
If Request(i) <= Need(i)then
go to step 2
else
raise an error condition, since the process has exceeded its maximum claim.
Step 2:
If Request(i) <= Availablethen
go to step 3
else
Pi must wait, since the resources are not available.
Step 3:
If the system want to allocate the requested resources to process Pi then modify thestate
as follows:
Available = Available – Request(i)
Allocation(i) = Allocation(i) + Request(i)
Need(i) = Need(i) – Request(i)
Step 4:
If the resulting resource-allocation state is safe,then
i) transaction is complete and
ii) Pi is allocated its resources.
Step 5:
If the new state is unsafe,
then i) Pi must wait for Request(i) and
ii) old resource-allocation state is restored.
Solution (i):
• The content of the matrix Need is given by
Need = Max - Allocation
• So, the content of Need Matrix is:
Need
A B C
P0 7 4 3
P1 1 2 2
P2 6 0 0
P3 0 1 1
P4 4 3 1
Solution (ii):
•Applying the Safety algorithm on the given system,
Step 1: Initialization
Work = Available i.e. Work =3 3 2
……P0………P1……..P2……..P3……
P4….. Finish = | false | false | false | false | false |
• A deadlock exists in the system if and only if the wait-for-graph contains a cycle.
• To detect deadlocks, the system needs to
→ maintain the wait-for-graph and
→ periodically execute an algorithm that searches for a cycle in the graph.
3-16
OPERATING
SYSTEMS Exercise Problems
Solution (i):
• The content of the matrix Need is given by
Need = Max - Allocation
• So, the content of Need Matrix is:
Need
A B C
P0 0 0 2
P1 1 0 1
P2 0 0 2
P3 2 1 0
P4 0 1 4
Solution (ii):
• Applying the Safety algorithm on the given system,
Step 1: Initialization
Work = Available i.e. Work =1 0 2
……P0………
P1……..P2……..P3……P4….. Finish = | false
| false | false | false | false |
3-17
OPERATING
SYSTEMS Finish[P2] = false and Need[P2]<=Work i.e. (0 0 2)<=(2 0 4) true So
P2 must be kept in safe sequence.
Step 3: Work = Work + Allocation[P2] =(2 0 4)+(1 3 5)=(3 3 9)
……P0…….P1…….P2… P3……P4….
Finish = | true | true | true | false | false |
3-18
OPERATING
SYSTEMS
Step 2: For i=3
Finish[P3] = false and Need[P3]<=Work i.e. (2 1 0)<=(3 3 9) true So
P3 must be kept in safe sequence.
Step 3: Work = Work + Allocation[P3] = (3 3 9)+(6 3 2)=(9 6 11)
…..P0……..P1……
P2……..P3…….P4…. Finish = | true | true |
true | true | false |
Need
A B C
P0 0 0 2
P1 1 0 1
P2 0 0 0
P3 2 1 0
P4 0 1 4
• To determine whether this new system state is safe, we again execute Safety algorithm. Step
3-19
OPERATING
SYSTEMS
1: Initialization
Work = Available i.e. Work =2 3 0
....P0………
P1…….P2……….P3…..P4….. Finish = |
false | false | false | false | false |
3-20
OPERATING
SYSTEMS
Step 2: For i=1
Finish[P1] = false and Need[P1]<=Work i.e. (1 0 1)<=(2 3 0) false So
P1 must wait.
3-21
OPERATING
SYSTEMS
2) For the following snapshot, find the safe sequence using Banker's algorithm:
The number of resource units is (A, B, C) which are (7, 7, 10) respectively.
Need
A B C
P1 1 4 5
P2 2 3 0
P3 2 2 0
• Applying the Safety algorithm on the given system,
Step 1: Initialization
Here, m=3, n=3
Work = Available i.e. Work =7 7 10
….P1………..P2… P3…
Finish = | false | false | false |
Step 2: For i=1
Finish[P1] = false and Need[P1]<=Work i.e. (1 4 5)<=(7 7 10) true So
P1 must be kept in safe sequence.
Step 3: Work = Work + Allocation[P1] =(7 7 10)+(2 2 3)=(9 9 13)
……P1……
P2……….P3…. Finish = | true
| false | false |
3-22
OPERATING
Conclusion:
SYSTEMSYes, the system is currently in a safe state.
3-23
OPERATING
SYSTEMS
3) Consider the following snapshot of resource-allocation at time t1.
Solution (i):
• The content of the matrix Need is given by
Need = Max - Allocation
• So, the content of Need Matrix is:
Need
A B C
P0 0 0 0
P1 0 0 2
P2 0 0 0
P3 0 0 0
P4 0 0 0
Solution (ii):
• Applying the Safety algorithm on the given system,
Step 1: Initialization
Work = Available i.e. Work =0 0 0
……P0………P1…….P2 P3……P4…
Finish = | false | false | false | false | false |
3-24
OPERATING
Step 2: For i=3
SYSTEMS
Finish[P3] = false and Need[P3]<=Work i.e. (0 0 0)<=(5 1 3) true So
P3 must be kept in safe sequence.
Step 3: Work = Work + Allocation[P3] = (5 1 3)+(2 1 1)=(5 2 4)
…P0……P1………
P2…….P3…….P4… Finish = | true | false |
true | true | false |
3-25
OPERATING
SYSTEMS
Step 2: For i=4
Finish[P4] = false and Need[P4]<=Work i.e. (0 0 0)<=(5 2 4) true So
P4 must be kept in safe sequence.
Step 3: Work = Work + Allocation[P4] =(5 2 4)+(0 0 2)=(5 2 6)
....P0……
P1…….P2…….P3…….P4…. Finish = |
true | false | true | true | true |
3-26
OPERATING
SYSTEMS
4) For the given snapshot :
Solution (i):
• The content of the matrix Need is given by
Need = Max - Allocation
• So, the content of Need Matrix is:
Need
A B C D
P1 0 0 0 0
P2 0 7 5 2
P3 1 0 0 2
P4 0 0 2 0
P5 0 6 4 2
Solution (ii):
• Applying the Safety algorithm on the given system,
Step 1: Initialization
Work = Available i.e. Work =1 5 2 0
....P1………
P2…….P3……….P4…..P5….. Finish = |
false | false | false | false | false |
3-27
OPERATING
Step 2: For i=4
SYSTEMS
Finish[P4] = false and Need[P4]<=Work i.e. (0 0 2 0)<=(2 8 8 6) true So
P4 must be kept in safe sequence.
Step 3: Work = Work + Allocation[P4] =(2 8 8 6)+(0 6 3 2)=(2 14 11 8)
....P1………
P2…….P3…….P4…….P5… Finish = |
true | false | true | true | false |
3-28
OPERATING
SYSTEMS
Step 2: For i=5
Finish[P5] = false and Need[P5]<=Work i.e. (0 6 4 2)<=(2 14 11 8) true So
P5 must be kept in safe sequence.
Step 3: Work = Work + Allocation[P5] =(2 14 11 8)+(0 0 1 4)=(2 14 12 12)
....P1………P2…….P3…….P4……
P5… Finish = | true | false | true | true | true |
3-29
OPERATING
SYSTEMS Finish = | false | false | false | false | false |
3-30
OPERATING
SYSTEMS
Step 3: Work = Work + Allocation[P1] =(1 1 0 0)+(0 0 1 2)=(1 1 1 2)
....P1………P2…….P3……...P4P5…
Finish = | true | false | false | false | false |
3-31
OPERATING
SYSTEMS
5) Consider a system containing ‘m’ resources of the same type being shared by ‘n’ processes. Resources
can be requested and released by processes only one at a time. Show that the system is deadlock free if the
following two conditions hold:
i) The maximum need of each process is between 1 and m resources
ii) The sum of all maximum needs is less than m+n.
Ans:
• Suppose N = Sum of all Needi
A = Sum of all
Allocationi M = Sum of
all Maxi.
• Use contradiction to prove: Assume this system is not deadlock free.
• If there exists a deadlock state, then A=m because there's only one kind of resource and resources can
be requested and released only one at a time.
• From condition (ii), N+A = M<m+n
• So we get N+m <m +n.
• So we get N < n.
• It shows that at least one process i that Needi=0.
• From condition (i), Pi can release at least one resource.
• So, there are n-1 processes sharing ‘m’ resources now, condition (i) and (ii) still hold.
• Go on the argument, no process will wait permanently, so there's no deadlock.
6) Consider the traffic deadlock depicted in the figure given below, explain that the four necessary
conditions for dead lock indeed hold in this examples.
Ans:
• The four necessary conditions for a deadlock are:
1) Mutual exclusion
2) Hold-and-wait
3) No preemption and
4) Circular-wait.
• The mutual exclusion condition holds since only one car can occupy a space in the roadway.
• Hold-and-wait occurs where a car holds onto its place in the roadway while it waits to advance in the
roadway.
• A car cannot be removed (i.e. preempted) from its position in the roadway.
• Lastly, there is indeed a circular-wait as each car is waiting for a subsequent car to advance.
• The circular-wait condition is also easily observed from the graphic.
3-32
OPERATING
SYSTEMS
3-33
OPERATING
SYSTEMS
3.9.2 Address Binding
• Address binding of instructions to memory-addresses can happen at 3 different stages (Figure 3.10):
1) Compile Time
If memory-location known a priori, absolute code can be generated.
Must recompile code if starting location changes.
2) Load Time
Must generate relocatable code if memory-location is not known at compile time.
3) Execution Time
Binding delayed until run-time if the process can be moved during its execution from one
memory-segment to another.
Need hardware support for address maps (e.g. base and limit-registers).
3-34
OPERATING
SYSTEMS
3-35
OPERATING
SYSTEMS
3.10 Swapping
• A process must be in memory to be executed.
• A process can be
→ swapped temporarily out-of-memory to a backing-store and
→ then brought into memory for continued execution.
• Backing-store is a fast disk which is large enough to accommodate copies of all memory-images for all
users.
• Roll out/Roll in is a swapping variant used for priority-based scheduling algorithms.
Lower-priority process is swapped out so that higher-priority process can be loaded and
executed.
Once the higher-priority process finishes, the lower-priority process can be swapped back in and
continued (Figure 3.12).
3-36
OPERATING
SYSTEMS
3.11 Contiguous Memory Allocation
• Memory is usually divided into 2 partitions:
→ One for the resident OS.
→ One for the user-processes.
• Each process is contained in a single contiguous section of memory.
3-37
OPERATING
SYSTEMS
3.11.2 Memory Allocation
• Two types of memory partitioning are: 1) Fixed-sized partitioning and
2) Variable-sized partitioning
1) Fixed-sized Partitioning
The memory is divided into fixed-sized partitions.
Each partition may contain exactly one process.
The degree of multiprogramming is bound by the number of partitions.
When a partition is free, a process is
→ selected from the input queue and
→ loaded into the free partition.
When the process terminates, the partition becomes available for another process.
2) Variable-sized Partitioning
The OS keeps a table indicating
→ which parts of memory are available and
→ which parts are occupied.
A hole is a block of available memory.
Normally, memory contains a set of holes of various sizes.
Initially, all memory is
→ available for user-processes and
→ considered one large hole.
When a process arrives, the process is allocated memory from a large hole.
If we find the hole, we
→ allocate only as much memory as is needed and
→ keep the remaining memory available to satisfy future requests.
• Three strategies used to select a free hole from the set of available holes.
1) First Fit
Allocate the first hole that is big enough.
Searching can start either
→ at the beginning of the set of holes or
→ at the location where the previous first-fit search ended.
2) Best Fit
Allocate the smallest hole that is big enough.
We must search the entire list, unless the list is ordered by size.
This strategy produces the smallest leftover hole.
3) Worst Fit
Allocate the largest hole.
Again, we must search the entire list, unless it is sorted by size.
This strategy produces the largest leftover hole.
• First-fit and best fit are better than worst fit in terms of decreasing time and storage utilization.
3-38
OPERATING
SYSTEMS
3.11.3 Fragmentation
• Two types of memory fragmentation: 1) Internal fragmentation and
2) External fragmentation
1) Internal Fragmentation
• The general approach is to
→ break the physical-memory into fixed-sized blocks and
→ allocate memory in units based on block size (Figure 3.14).
• The allocated-memory to a process may be slightly larger than the requested-memory.
• The difference between requested-memory and allocated-memory is called internal fragmentation i.e.
Unused memory that is internal to a partition.
2) External Fragmentation
• External fragmentation occurs when there is enough total memory-space to satisfy a request but the
available-spaces are not contiguous. (i.e. storage is fragmented into a large number of small holes).
• Both the first-fit and best-fit strategies for memory-allocation suffer from external fragmentation.
• Statistical analysis of first-fit reveals that
→ given N allocated blocks, another 0.5 N blocks will be lost to fragmentation.
This property is known as the 50-percent rule.
• Two solutions to external fragmentation (Figure 3.15):
1) Compaction
The goal is to shuffle the memory-contents to place all free memory together in one large
hole.
Compaction is possible only if relocation is
→ dynamic and
→ done at execution-time.
2) Permit the logical-address space of the processes to be non-contiguous.
This allows a process to be allocated physical-memory wherever such memory is available.
Two techniques achieve this solution:
1) Paging and
2) Segmentation.
3-39
OPERATING
SYSTEMS
3.13 Paging
• Paging is a memory-management scheme.
• This permits the physical-address space of a process to be non-contiguous.
• This also solves the considerable problem of fitting memory-chunks of varying sizes onto the
backing-store.
• Traditionally: Support for paging has been handled by hardware.
Recent designs: The hardware & OS are closely integrated.
3-40
OPERATING
SYSTEMS
3-41
OPERATING
SYSTEMS
• The page-size (like the frame size) is defined by the hardware (Figure 3.18).
• If the size of the logical-address space is 2m, and a page-size is 2n addressing-units (bytes or words) then
the high-order m-n bits of a logical-address designate the page-number, and the n low-order bits designate
the page-offset.
Figure 3.18 Free frames (a) before allocation and (b) after allocation
3-42
OPERATING
SYSTEMS
3.13.2 Hardware Support for Paging
• Most OS's store a page-table for each process.
• A pointer to the page-table is stored in the PCB.
Translation Lookaside Buffer
• The TLB is associative, high-speed memory.
• The TLB contains only a few of the page-table entries.
• Working:
When a logical-address is generated by the CPU, its page-number is presented to the TLB.
If the page-number is found (TLB hit), its frame-number is
→ immediately available and
→ used to access memory.
If page-number is not in TLB (TLB miss), a memory-reference to page table must be made.
The obtained frame-number can be used to access memory (Figure 3.19).
In addition, we add the page-number and frame-number to the TLB, so that they will be
found quickly on the next reference.
• If the TLB is already full of entries, the OS must select one for replacement.
• Percentage of times that a particular page-number is found in the TLB is called hit ratio.
• Advantage: Search operation is fast.
Disadvantage: Hardware is expensive.
• Some TLBs have wired down entries that can't be removed.
• Some TLBs store ASID (address-space identifier) in each entry of the TLB that uniquely
→ identify each process and
→ provide address space protection for that process.
3-43
OPERATING
SYSTEMS
3.13.3 Protection
• Memory-protection is achieved by protection-bits for each frame.
• The protection-bits are kept in the page-table.
• One protection-bit can define a page to be read-write or read-only.
• Every reference to memory goes through the page-table to find the correct frame-number.
• Firstly, the physical-address is computed. At the same time, the protection-bit is checked to verify that
no writes are being made to a read-only page.
• An attempt to write to a read-only page causes a hardware-trap to the OS (or memory-protection
violation).
Valid Invalid Bit
• This bit is attached to each entry in the page-table (Figure 3.20).
1) Valid bit: The page is in the process’ logical-address space.
2) Invalid bit: The page is not in the process’ logical-address space.
• Illegal addresses are trapped by use of valid-invalid bit.
• The OS sets this bit for each page to allow or disallow access to the page.
3-44
OPERATING
SYSTEMS
3.13.4 Shared Pages
• Advantage of paging:
1) Possible to share common code.
• Re-entrant code is non-self-modifying code, it never changes during execution.
• Two or more processes can execute the same code at the same time.
• Each process has its own copy of registers and data-storage to hold the data for the process's execution.
• The data for 2 different processes will be different.
• Only one copy of the editor need be kept in physical-memory (Figure 3.21).
• Each user's page-table maps onto the same physical copy of the editor, but
data pages are mapped onto different frames.
• Disadvantage:
1) Systems that use inverted page-tables have difficulty implementing shared-memory.
3-45
OPERATING
SYSTEMS
3.14 Structure of the Page Table
1) Hierarchical Paging
2) Hashed Page-tables
3) Inverted Page-tables
3.14.1 Hierarchical Paging
• Problem: Most computers support a large logical-address space (232 to 264). In these systems, the
page-table itself becomes excessively large.
Solution: Divide the page-table into smaller pieces.
Two Level Paging Algorithm
• The page-table itself is also paged (Figure 3.22).
• This is also known as a forward-mapped page-table because address translation works from the outer
page-table inwards.
• For example (Figure 3.23):
Consider the system with a 32-bit logical-address space and a page-size of 4 KB.
A logical-address is divided into
→ 20-bit page-number and
→ 12-bit page-offset.
Since the page-table is paged, the page-number is further divided into
→ 10-bit page-number and
→ 10-bit page-offset.
Thus, a logical-address is as follows:
3-46
OPERATING
SYSTEMS
3.14.2 Hashed Page Tables
• This approach is used for handling address spaces larger than 32 bits.
• The hash-value is the virtual page-number.
• Each entry in the hash-table contains a linked-list of elements that hash to the same location (to
handle collisions).
• Each element consists of 3 fields:
1) Virtual page-number
2) Value of the mapped page-frame and
3) Pointer to the next element in the linked-list.
• The algorithm works as follows (Figure 3.24):
1) The virtual page-number is hashed into the hash-table.
2) The virtual page-number is compared with the first element in the linked-list.
3) If there is a match, the corresponding page-frame (field 2) is used to form the desired
physical-address.
4) If there is no match, subsequent entries in the linked-list are searched for a matching virtual page-
number.
Clustered Page Tables
• These are similar to hashed page-tables except that each entry in the hash-table refers to several pages
rather than a single page.
• Advantages:
1) Favorable for 64-bit address spaces.
2) Useful for address spaces, where memory-references are noncontiguous and scattered
throughout the address space.
3-47
OPERATING
SYSTEMS
3.14.3 Inverted Page Tables
• Has one entry for each real page of memory.
• Each entry consists of
→ virtual-address of the page stored in that real memory-location and
→ information about the process that owns the page.
3-48
OPERATING
SYSTEMS
3.15 Segmentation
3.15.1 Basic Method
• This is a memory-management scheme that supports user-view of memory(Figure 3.26).
• A logical-address space is a collection of segments.
• Each segment has a name and a length.
• The addresses specify both
→ segment-name and
→ offset within the segment.
• Normally, the user-program is compiled, and the compiler automatically constructs segments
reflecting the input program.
For ex:
→ The code → Global variables
→ The heap, from which memory is allocated → The stacks used by each thread
→ The standard C library
4-2