chp6 Os
chp6 Os
(ASSIGNMENT 2)
Major: BSIT-IV
Section: B
UNIVERSITY OF GUJRAT
while (true) {
; /* do nothing */
count++;
while (true) {
while (count == 0)
; /* do nothing */
count--;
5
Rules to be followed by processes whenever they are accessing their critical section
6
General Structure of a Process
The structure of a process handling the critical-section problem typically looks like this:
c
Copy code
while (true) {
// entry section: request permission to enter the critical section
critical_section();
// exit section: signal that the critical section is done
remainder_section();
}
The race condition occurs when two or more processes try to access and modify shared data
concurrently, leading to unpredictable results. The image you provided shows a race condition
scenario when assigning a process ID (PID) in an operating system.
1. Processes P0 and P1 both want to create a child process using the fork() system call.
2. Each process requests the next available PID from the system.
3. The system returns the same PID (2615) to both processes because they both requested it
before the system could update the next_available_pid.
7
4. Both processes end up with child processes having the same PID (2615), which can cause
significant issues in process management.
This situation occurs because there is no mutual exclusion when accessing and updating the
next_available_pid. Both processes can read and modify this variable concurrently, leading to
the race condition.
In operating systems, there are two general approaches to handle critical sections:
To prevent race conditions, the kernel can use various synchronization mechanisms such as:
• Locks: Ensure that only one process can access a critical section at a time.
• Semaphores: Control access to shared resources by using counters.
• Monitors: Encapsulate shared variables, the operations that can be performed on them, and the
synchronization necessary to ensure mutual exclusion.
Summary
The critical-section problem is a key issue in concurrent programming where processes need to
safely access shared resources. Solutions must ensure mutual exclusion, progress, and bounded
waiting. The example of the race condition in assigning PIDs illustrates the need for careful
synchronization in system-level programming to prevent data corruption and ensure system
stability.
8
9
What is a Semaphore?
Types of Semaphores
1. Counting Semaphore:
o This type of semaphore can have any integer value.
o It is used to manage a resource that has a limited number of instances.
o For example, if there are 5 printers available, a counting semaphore can be initialized to
5. Each time a printer is used, the semaphore is decremented. When a printer is
released, the semaphore is incremented.
2. Binary Semaphore (or Mutex Lock):
o This type of semaphore can only have the value 0 or 1.
o It is used to ensure mutual exclusion, meaning only one process can access the resource
at a time.
o It behaves like a lock: 0 means the resource is locked (not available), and 1 means the
resource is unlocked (available).
10
Operations on Semaphores
c
Copy code
wait(S) {
while (S <= 0)
; // busy wait
S--;
}
c
Copy code
signal(S) {
S++;
}
Suppose we have 3 printers (a shared resource) and multiple processes that need to print
documents.
1. Initialization:
o Initialize a counting semaphore printerSemaphore to 3 (since there are 3 printers).
c
Copy code
semaphore printerSemaphore = 3;
11
o If printerSemaphore > 0, the process gets a printer and printerSemaphore is
decremented.
o If printerSemaphore == 0, the process waits (busy wait).
c
Copy code
wait(printerSemaphore);
// Process uses a printer
c
Copy code
// Process finishes using the printer
signal(printerSemaphore);
Semaphores can be used to solve various synchronization problems. One common problem is
ensuring the correct sequence of operations between processes.
Suppose we have two processes, P1 and P2. We want to ensure that P2 runs a specific operation
only after P1 has completed its operation.
1. Initialize Semaphore:
o Initialize a binary semaphore synch to 0.
c
Copy code
semaphore synch = 0;
2. Process P1:
o P1 performs its operation and then signals the semaphore.
c
Copy code
P1 {
// Perform operation S1
signal(synch);
}
3. Process P2:
o P2 waits on the semaphore. It will only proceed with its operation when the semaphore
is signaled by P1.
12
c
Copy code
P2 {
wait(synch);
// Perform operation S2
}
Implementing Semaphores
1. Data Structure:
o A semaphore can be represented as a structure containing an integer value and a list of
waiting processes.
c
Copy code
typedef struct {
int value;
struct process *list;
} semaphore;
2. Wait Operation:
o Decrement the semaphore value.
o If the value is less than zero, add the process to the waiting list and suspend it.
c
Copy code
wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
sleep();
}
}
3. Signal Operation:
o Increment the semaphore value.
o If the value is zero or negative, remove a process from the waiting list and wake it up.
c
Copy code
signal(semaphore *S) {
S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}
Conclusion
Semaphores are powerful tools for managing concurrent access to shared resources. They help in
solving synchronization problems by ensuring mutual exclusion and proper sequencing of
operations. Understanding how to use and implement semaphores is crucial for developing
reliable and efficient concurrent systems.
14
Understanding Monitors
Monitors are a high-level synchronization construct that provides a convenient mechanism for
process synchronization. They help prevent timing errors that can occur with the incorrect use of
lower-level synchronization primitives like semaphores or mutex locks.
15
Only one process can be active within the monitor at a time, which ensures mutual exclusion.
This means that no two processes can be inside the monitor simultaneously.
Structure of a Monitor
• Shared Data: The variables that represent the state of the monitor.
• Operations: The functions that can be executed within the monitor. These operations ensure
mutual exclusion.
• Initialization Code: Code that sets up the initial state of the shared data.
pseudocode
Copy code
monitor MonitorName {
// Shared variable declarations
shared data;
// Initialization code
initialization {
// Initialize shared data
}
// Operations
function Operation1(...) {
...
}
function Operation2(...) {
...
}
...
function OperationN(...) {
...
}
}
Condition Variables
Monitors use condition variables for more complex synchronization. Condition variables enable
processes to wait within the monitor until a particular condition is true.
16
o x.signal(); - Resumes exactly one suspended process. If no process is suspended, it
has no effect.
Figures Explanation
Monitors can be implemented using semaphores. Each monitor uses a binary semaphore (mutex)
to ensure mutual exclusion.
• Mutex Semaphore: Ensures that only one process is active within the monitor.
• Condition Variables Implementation:
o Binary Semaphore for Each Condition: x_sem, initialized to 0.
o Counter for Each Condition: x_count, initialized to 0.
When a process is resumed after waiting on a condition variable, it’s important to determine the
order of resumption:
• First-Come, First-Served (FCFS): The simplest method where the first process to wait is the first
to be resumed.
17
• Conditional Wait: Processes can wait with a priority number, and the process with the smallest
priority number is resumed first.
Here’s an example of a monitor that allocates a single resource among competing processes:
pseudocode
Copy code
monitor ResourceAllocator {
boolean busy;
condition x;
void release() {
busy = false;
x.signal();
}
initialization {
busy = false;
}
}
In this example:
Conclusion
18
Chp 5:
Introduction:
Single CPU Core and Process Execution
• Single CPU Core: In a computer with only one CPU core, only one process (task or
program) can be executed at a time.
• Waiting Processes: Any other processes that need to be run must wait until the CPU
becomes available.
Multiprogramming
• Goal: The main aim of multiprogramming is to keep the CPU busy by having some
process running at all times. This maximizes CPU utilization, meaning the CPU is not
sitting idle and wasting time.
1. Execution Until Wait: A process runs on the CPU until it needs to wait for something,
usually an I/O operation (like reading data from a disk or waiting for user input).
2. Idle CPU in Simple Systems: In a simple system without multiprogramming, the CPU
would just sit idle during this wait time, doing nothing productive.
3. Productive Use of Time in Multiprogramming: Instead of letting the CPU sit idle,
multiprogramming keeps several processes in memory simultaneously.
4. Process Switch: When one process needs to wait, the operating system switches the CPU
to another process that is ready to run.
5. Continuous Pattern: This pattern continues, ensuring that whenever one process has to
wait, another process can use the CPU. This way, the CPU is always doing useful work.
Summary
Multiprogramming is a technique used to keep the CPU busy by switching between processes
whenever one process needs to wait, ensuring that the CPU is always working on something
productive. This maximizes CPU utilization and improves the efficiency of the system.
Let's break down the concepts shown in the images and the explanation about CPU scheduling
and burst durations.
1. CPU Burst: This is a period during which a process is actively using the CPU for
computations.
o Example activities: load, store, add, read from file.
2. I/O Burst: This is a period during which a process is waiting for an I/O operation to
complete.
o Example activities: wait for I/O.
3. Alternation Between CPU and I/O Bursts: A process alternates between these bursts:
o A process starts with a CPU burst.
o When it needs to wait for I/O, it enters an I/O burst.
o Once the I/O operation is complete, it goes back to a CPU burst.
o This cycle continues until the process finishes execution.
20
3. I/O-Bound vs. CPU-Bound Programs:
o I/O-Bound Programs: These programs perform a lot of I/O operations. They have many
short CPU bursts because they quickly go back to waiting for I/O.
o CPU-Bound Programs: These programs perform intensive computations with fewer I/O
operations. They have fewer but longer CPU bursts.
Understanding the nature of CPU and I/O bursts helps in designing effective CPU scheduling
algorithms:
• For I/O-Bound Programs: Since they have many short CPU bursts, they often need to frequently
switch between CPU and I/O.
• For CPU-Bound Programs: Since they have longer CPU bursts, they benefit from fewer
interruptions to maximize their CPU usage.
Let's break down the concept of the CPU Scheduler in simpler terms:
Key Points
21
oThis process is chosen from those currently in memory and ready to execute.
3. Implementation of the Ready Queue:
o The ready queue is not necessarily organized in a first-in, first-out (FIFO) manner.
It can be implemented in various ways, depending on the scheduling algorithm
used.
o FIFO Queue: Processes are queued in the order they arrive.
o Priority Queue: Processes are queued based on their priority levels.
o Tree Structure: Processes are organized in a hierarchical structure.
o Unordered Linked List: Processes are stored in a list without any specific order.
4. Process Control Blocks (PCBs):
o The records in the ready queue are generally process control blocks (PCBs).
o PCB: This is a data structure used by the operating system to store information
about each process. It includes details like the process ID, state, priority, and other
relevant information.
o
o Summary
• The CPU Scheduler is responsible for selecting which process runs on the CPU when it
becomes idle.
• The Ready Queue contains processes that are ready to run. It can be organized in
different ways (FIFO, priority queue, tree, unordered list).
• The records in the ready queue are Process Control Blocks (PCBs), which store
information about each process.
By efficiently managing the ready queue and selecting processes, the CPU scheduler ensures that
the CPU is utilized effectively and processes are executed in an optimal order.
22
CPU Scheduling Decisions
Scheduling Types
Nonpreemptive (Cooperative) Scheduling:
Scheduling occurs only in situations 1 and 4.
Once the CPU is allocated to a process, it runs until it either terminates or switches to the waiting
state.
No process can be preempted to start another process.
Simpler to implement but not suitable for modern multitasking systems.
Preemptive Scheduling:
Scheduling can occur in all four situations, including 2 and 3.
The CPU can be taken away from a running process and allocated to another process.
Allows better responsiveness and utilization of the CPU.
Modern operating systems like Windows, macOS, Linux, and UNIX use preemptive scheduling.
Challenges with Preemptive Scheduling
Race Conditions:
Occur when processes share data.
If one process is preempted while updating shared data, another process might read inconsistent
data.
Requires mechanisms like mutex locks to prevent data corruption.
Kernel Design:
Nonpreemptive Kernel:
Waits for system calls to complete or processes to block before switching.
Ensures kernel data structures remain consistent.
Not ideal for real-time systems where tasks have strict timing requirements.
Preemptive Kernel:
Can preempt processes even during kernel operations.
Needs to handle synchronization to maintain data consistency.
Better suited for real-time and multitasking environments.
Summary
Dispatcher: Manages the process of switching the CPU from one process to another, involving
saving and restoring process states.
Nonpreemptive Scheduling: Simpler but less responsive, processes run until they finish or wait.
23
Preemptive Scheduling: More complex but allows better CPU utilization and responsiveness by
preempting processes when necessary.
Challenges: Includes handling race conditions and ensuring kernel data consistency.
By understanding these concepts, you can see how modern operating systems manage
multitasking efficiently while addressing potential issues with shared data and kernel operations.
Dispatcher
The dispatcher is a critical component in the CPU scheduling function. It is responsible for
giving control of the CPU core to the process selected by the CPU scheduler.
1. Switching Context:
o The dispatcher saves the state of the currently running process and loads the state
of the next process to be executed.
o This process involves saving and restoring information such as the program
counter, CPU registers, and memory management information.
2. Switching to User Mode:
o After the context switch, the dispatcher switches the CPU to user mode from
kernel mode.
o User mode is a restricted mode of operation designed to protect the system from
malicious or erroneous user programs.
24
3. Jumping to the Proper Location in the User Program:
o The dispatcher sets the program counter to the appropriate location in the user
program to resume execution.
• The dispatcher should perform its tasks as quickly as possible because it is invoked
during every context switch.
• The time it takes for the dispatcher to stop one process and start another is known as
dispatch latency.
• Dispatch Latency: This is the time overhead involved in switching from one process to
another. Reducing dispatch latency is important to minimize the overhead and ensure
efficient CPU utilization.
• Context switches occur whenever the CPU is allocated from one process to another.
• Voluntary Context Switch: Occurs when a process voluntarily gives up the CPU, for
example, when it performs an I/O operation.
• Nonvoluntary Context Switch: Occurs when the CPU is taken away from a process,
such as when its timeslice expires or it is preempted by a higher-priority process.
• On Linux systems, the number of context switches can be monitored using the vmstat
command.
• Example Command: vmstat 1 3
o This command provides three lines of output over a 1-second delay.
o The first line gives the average number of context switches per second since the
system booted.
o The next two lines give the number of context switches over two 1-second
intervals.
o The output may look something like this:
css
Copy code
------cpu----
24
225
339
Summary
25
• Dispatcher: The module responsible for handing over control of the CPU core to the
selected process, performing context switches, switching to user mode, and jumping to
the correct location in the user program.
• Dispatch Latency: The time taken to perform a context switch, which should be
minimized for efficient CPU utilization.
• Context Switch Frequency: Indicates how often context switches occur, which can be
monitored using tools like vmstat on Linux systems.
Understanding the dispatcher's role and how context switches work is crucial for optimizing
CPU scheduling and improving overall system performance.
Scheduling Criteria
1. CPU Utilization:
o Definition: The percentage of time the CPU is actively working (not idle).
o Objective: To keep the CPU as busy as possible.
o Range: Conceptually from 0% to 100%. In real systems, it ranges from 40%
(lightly loaded) to 90% (heavily loaded).
o Measurement Tool: Can be measured using the top command on Linux, macOS,
and UNIX systems.
2. Throughput:
o Definition: The number of processes completed per time unit.
o Objective: To maximize the number of processes completed in a given period.
o Variation: Long processes may result in lower throughput (e.g., one process
every few seconds), while short processes may result in higher throughput (e.g.,
tens of processes per second).
3. Turnaround Time:
o Definition: The total time taken for a process to complete from submission to
completion.
o Components: Sum of the periods spent waiting in the ready queue, executing on
the CPU, and performing I/O operations.
o Objective: To minimize the time taken to execute a process completely.
4. Waiting Time:
o Definition: The total time a process spends waiting in the ready queue.
o Objective: To minimize the time processes spend waiting to be executed.
o Note: Scheduling algorithms directly affect waiting time but do not affect the
actual time a process spends executing or performing I/O.
5. Response Time:
o Definition: The time from the submission of a request until the first response is
produced.
o Objective: To minimize the time it takes to start responding to a request.
26
o Relevance: Particularly important in interactive systems where immediate
feedback is crucial.
o Difference from Turnaround Time: Response time focuses on the time to start
producing output, whereas turnaround time focuses on the total time to complete
the process.
• Maximize:
o CPU Utilization: Keep the CPU busy as much as possible.
o Throughput: Increase the number of processes completed in a given time frame.
• Minimize:
o Turnaround Time: Reduce the total time taken for processes to complete.
o Waiting Time: Reduce the time processes spend waiting in the ready queue.
o Response Time: Decrease the time to start responding to requests.
Summary
When evaluating CPU scheduling algorithms, the goal is to choose one that maximizes CPU
utilization and throughput while minimizing turnaround time, waiting time, and response time.
The choice of algorithm can significantly impact the performance of a system, especially
depending on whether it is more CPU-bound or I/O-bound, and whether it is an interactive or
batch processing system.
Basic Concept
• Multiple Queues: Processes are divided into different queues based on specific criteria like
process type or priority.
• Static Assignment: Once a process is assigned to a queue, it remains in that queue for its entire
runtime.
• Priority Levels: Each queue has a priority level, and processes in higher-priority queues are
scheduled before those in lower-priority queues.
Example Structure
Consider a system with four queues, each representing a different type of process:
27
2. System processes
3. Interactive processes
4. Batch processes: Lowest priority
• Each queue can have its own scheduling algorithm. For example:
o Real-time queue: May use a fixed-priority preemptive scheduling algorithm.
o Interactive queue: May use a Round-Robin (RR) algorithm to ensure fair CPU time
allocation among interactive processes.
o Batch queue: May use a First-Come, First-Served (FCFS) algorithm since batch processes
can typically tolerate longer waits.
Example Scenario
• High-Priority Preemption: If an interactive process enters the ready queue while a batch
process is running, the batch process is immediately preempted to allow the interactive process
to run.
• Time-Slice Allocation: The foreground queue (interactive processes) receives 80% of the CPU
time, scheduled using RR. The background queue (batch processes) receives 20% of the CPU
time, scheduled using FCFS.
• Customizable Scheduling: Allows different scheduling algorithms to be used for different types
of processes, optimizing for their specific needs.
• Priority Handling: Ensures high-priority processes (like real-time processes) get immediate CPU
access,. improving response times for critical tasks.
• Fair Allocation: Time-slicing ensures that lower-priority processes also get a share of the CPU,
preventing starvation.
Summary
28
Multilevel Queue Scheduling is a versatile and efficient method for managing diverse types of
processes in a system. By organizing processes into multiple queues with distinct scheduling
algorithms and priority levels, it balances the need for quick response times in interactive
applications with the efficient processing of batch jobs.
Key Features
1. Dynamic Queue Assignment: Processes can move between different priority queues
based on their CPU usage and waiting time.
2. Priority Adjustment: Processes that use too much CPU time are demoted to lower-
priority queues, while those that wait too long in lower-priority queues can be promoted
to higher-priority queues to prevent starvation.
Example Structure
Process Movement
1. Initial Placement: A new process is placed in the highest-priority queue (Queue 0).
29
2. Execution and Demotion:
o A process in Queue 0 is given a time quantum of 8 milliseconds.
o If it does not complete within this time, it is moved to the tail of Queue 1.
o Queue 1 processes are given a time quantum of 16 milliseconds.
o If a process in Queue 1 does not complete within this time, it is moved to Queue
2.
o Processes in Queue 2 are executed using FCFS but only when Queues 0 and 1 are
empty.
3. Promotion (Aging): A process waiting too long in a lower-priority queue may be
gradually moved to a higher-priority queue to prevent starvation.
• Priority Order Execution: The scheduler first executes processes in the highest-priority
queue (Queue 0). Only when Queue 0 is empty does it execute processes in Queue 1, and
so on.
• Preemption: A process in a higher-priority queue can preempt a running process in a
lower-priority queue. For instance, a process arriving in Queue 0 can preempt a process
running in Queue 1 or Queue 2.
Example Scenario
Imagine a process that requires more CPU time than allocated by its current queue:
• Start in Queue 0: It runs for 8 milliseconds but doesn't finish, so it's moved to Queue 1.
• Move to Queue 1: It runs for 16 milliseconds but still doesn't finish, so it's moved to
Queue 2.
• Execution in Queue 2: Now it runs using FCFS but only when Queues 0 and 1 are
empty.
• Prevention of Starvation: If it waits too long in Queue 2, it may be moved back up to
Queue 1 to ensure it gets CPU time eventually.
30
• Flexibility: MLFQ can be tailored to match the specific needs of different systems by
adjusting its parameters.
• Efficiency: It optimizes CPU utilization by adjusting process priorities based on their
behavior.
• Prevention of Starvation: The aging mechanism ensures that processes are not
indefinitely deprived of CPU time.
However, the complexity of MLFQ lies in defining the optimal values for its parameters, which
requires a thorough understanding of the system's workload and behavior.
In summary, Multilevel Feedback Queue Scheduling is a powerful and adaptive CPU scheduling
algorithm that balances the need for responsive interactive processes and efficient batch
processing, making it suitable for a wide range of computing environments.
Multi-Processor Scheduling
Overview
31
o Multicore CPUs: Multiple cores on a single chip.
o Multithreaded Cores: Cores capable of running multiple threads simultaneously.
o NUMA (Non-Uniform Memory Access) Systems: Memory access time depends on
memory location relative to the processor.
o Heterogeneous Multiprocessing: Cores with varying clock speeds and power
management capabilities.
By understanding these key points, you can grasp the essentials of multi-processor scheduling,
its evolution, and the different system architectures involved.
• Description: All scheduling decisions, I/O processing, and system activities are managed by a
single processor (the master server). Other processors execute only user code.
• Advantages: Simplifies data structure access since only one core is involved.
• Disadvantages: The master server can become a bottleneck, reducing overall system
performance.
• Description: Each processor is self-scheduling, meaning every processor can handle its own
scheduling.
• Scheduling Strategies:
1. Common Ready Queue: All threads are in a single queue, and any processor can pick
the next thread to run.
2. Per-Core Private Queue: Each processor has its own queue of threads.
• Modern operating systems like Windows, Linux, macOS, Android, and iOS support SMP, making
it the standard approach for multiprocessor systems.
32
Multicore Processors
Memory Stall
A memory stall occurs when a processor spends significant time waiting for data to become
available from memory, often because modern processors operate much faster than memory.
This can also happen due to a cache miss. As illustrated in Figure 5.12, processors can spend up
to 50% of their time waiting for data from memory.
33
Chip Multithreading (CMT)
To address memory stalls, recent hardware designs have implemented multithreaded processing
cores where multiple hardware threads are assigned to each core. If one hardware thread stalls,
the core can switch to another thread. This is known as chip multithreading (CMT).
34
Scheduling with Multicore Processors
Scheduling becomes more complex with multicore processors, especially when considering
resource sharing:
• Core Sharing: If two software threads run on the same core, they share processor resources and
may proceed more slowly compared to running on separate cores.
• Resource Awareness: The operating system scheduler can make more effective decisions if it is
aware of resource sharing levels. For instance, it can schedule software threads onto logical
processors that do not share resources, optimizing performance.
Load Balancing
In SMP systems, load balancing ensures that the workload is evenly distributed across all
processors. Without load balancing, some processors might sit idle while others have high
workloads and long ready queues. Load balancing is mainly necessary for systems where each
processor has its own private ready queue. In systems with a common run queue, load balancing
is automatic as idle processors can take tasks from the common queue.
35
Approaches to Load Balancing
1. Push Migration: A dedicated task periodically checks the load on each processor. If an
imbalance is detected, it redistributes threads from overloaded processors to idle or less-busy
processors.
2. Pull Migration: When a processor becomes idle, it pulls a waiting task from a busy processor to
balance th e workload.
Processor Affinity
Processor affinity refers to the tendency to keep a process running on the same processor to take
advantage of cache memory.
• Soft Affinity: The operating system tries to keep a process on the same processor but does not
guarantee it. This approach reduces the overhead of cache invalidation and repopulation.
• Hard Affinity: Allows a process to specify a subset of processors on which it can run, providing
more control over processor assignment.
• Linux: Implements soft affinity but also supports hard affinity through the
sched_setaffinity() system call, which allows a thread to specify the set of CPUs it can run
on.
By understanding load balancing and processor affinity, systems can optimize performance and
efficiency, ensuring that processors are utilized effectively and processes benefit from improved
cache performance.
In Heterogeneous Multiprocessing (HMP), systems are designed with cores that, while running
the same instruction set, differ in clock speed and power management capabilities. This includes
the ability to adjust the power consumption of a core, even to the point of idling it.
Key Points:
• Core Variability: Cores can vary in clock speed and power management features.
• Power Management: Ability to dynamically adjust power consumption of each core.
• Idle Cores: Can reduce power consumption to the point of idling a core when not in use.
• Mobile Systems: HMP is commonly used in mobile systems to balance performance and power
efficiency, enhancing battery life while maintaining adequate performance.
36
Understanding HMP allows for better optimization of resources, providing a balance between
performance and energy efficiency in modern computing systems.
• Soft Real-Time Systems: These systems give preference to critical processes over non-critical
ones but do not guarantee when the process will be scheduled.
• Hard Real-Time Systems: These systems have strict deadlines. A task must be serviced by its
deadline; otherwise, it is considered as no service at all.
Minimizing Latency
Interrupt Latency
• Definition: The time from when an interrupt arrives at the CPU to the start of the interrupt
service routine (ISR).
• Process: Upon an interrupt, the operating system must:
1. Complete the current instruction.
2. Determine the type of interrupt.
3. Save the current process state.
4. Service the interrupt using the ISR.
Dispatch Latency
• Definition: The time required for the scheduler to stop one process and start another.
• Importance: Real-time operating systems aim to minimize dispatch latency to ensure timely task
execution.
• Technique: The most effective way to reduce dispatch latency is by using preemptive kernels.
In hard real-time systems, dispatch latency is usually measured in microseconds to meet strict
timing requirements. By minimizing both interrupt and dispatch latency, real-time operating
systems can provide immediate CPU access to critical tasks, ensuring timely and reliable
execution.
37
Priority-Based Scheduling in Real-Time Systems
Key Features
• Immediate Response: The scheduler must respond immediately to a real-time process when it
requires the CPU.
• Priority-Based Algorithm: Real-time operating systems use a priority-based scheduling
algorithm.
Preemption
Process Characteristics
38
5.6.3 Rate-Monotonic Scheduling (RMS)
• Static Priority Policy: Periodic tasks are scheduled using fixed priorities with preemption.
• Priority Assignment:
o Inversely based on period length.
o Shorter periods = Higher priority.
o Longer periods = Lower priority.
• Assumptions:
o The processing time for each CPU burst is constant.
• Example:
o Two processes, P1 and P2, with periods 50 and 100 respectively.
o Processing times: t1 = 20 for P1, t2 = 35 for P2.
o CPU utilization: P1 (20/50 = 0.40), P2 (35/100 = 0.35).
o Total CPU utilization = 75%.
• Allocation of Shares:
39
o Total shares (T) are divided among applications.
o Each application receives N shares of time, ensuring it gets N/T of total processor time.
• Example:
o T = 100 shares.
o Process A: 50 shares (50% of CPU time).
o Process B: 15 shares (15% of CPU time).
o Process C: 20 shares (20% of CPU time).
chp 7:
40
41
42
43
Reader–writer locks are most useful in the following situations:
• In applications where it is easy to identify which processes only read shared data and which
processes only write shared data.
• In applications that have more readers than writers. This is because reader–writer locks generally
require more overhead to establish than semaphores or mutual-exclusion locks. The increased
concurrency of allowing multiple readers compensates for the overhead involved in setting up the
reader–writer lock.
Problem Description
• Scenario: Five philosophers sit around a circular table, alternating between thinking and eating.
• Resources: There is a bowl of rice and five chopsticks.
• Behavior:
o Philosophers think and do not interact with others while thinking.
o When hungry, a philosopher picks up the two chopsticks closest to them (one on the left
and one on the right).
44
o A philosopher can only pick up one chopstick at a time and cannot pick up a chopstick
already in use by a neighbor.
o Once both chopsticks are picked up, the philosopher eats. After eating, both chopsticks
are put down, and the philosopher resumes thinking.
Synchronization Problem
• Goal: Allocate resources (chopsticks) among philosophers without deadlock and starvation.
Semaphore-Based Approach
semaphore chopstick[5];
// All elements of chopstick are initialized to 1
Deadlock Issue
• Deadlock Example: If all philosophers grab their left chopstick simultaneously, all will wait
indefinitely for the right chopstick.
Monitor-Based Approach
• Condition Variable:
45
condition self[5];
• Rules: A philosopher can set state[i] = EATING only if neither of their neighbors is eating:
DiningPhilosophers.pickup(i);
...
eat
...
DiningPhilosophers.putdown(i);
• Monitor Solution: This ensures a philosopher picks up both chopsticks only if they are
both available, preventing deadlock and ensuring fair resource allocation.
CHP 8:
In a multiprogramming environment, several threads may compete for a finite number of
resources. A thread requests resources; if the resources are not available at that time, the thread
enters a waiting state. Sometimes, a waiting thread can never again change state, because the
resources it has requested are held by other waiting threads. This situation is called a deadlock.
1.Overview
• System Resources: A system has a limited number of resources shared among multiple threads.
• Resource Types: Resources are grouped into types (or classes), each with identical instances.
Examples include CPU cycles, files, and I/O devices like network interfaces and DVD drives.
2.Resource Allocation
• Instance Example: If there are four CPUs, the CPU resource type has four instances.
• Request Handling: Any instance of a resource type should fulfill a thread's request. If not, the
resource types are not correctly defined.
46
2. Use: The thread uses the resource (e.g., accessing a critical section if the resource is a mutex lock).
3. Release: The thread releases the resource.
5.System Monitoring
• Resource Tracking: The OS checks and records resource allocation in a system table, noting
whether a resource is free or allocated and to which thread.
6. Deadlock Situation
• Definition: A deadlock occurs when every thread in a set waits for an event that only another
thread in the set can trigger.
• Example with Philosophers: If all philosophers (threads) grab the left chopstick (resource)
simultaneously, none can get the right chopstick, causing a deadlock as each waits for the right
chopstick to become available.
Components:
Graph Representation:
47
Example from Figure 8.4:
• No Cycle: No deadlock.
• Cycle Present:
o If each resource type has one instance: Cycle implies deadlock.
o If resource types have multiple instances: Cycle does not always mean deadlock.
48
Figure 8.6: Resource-Allocation Graph with a Cycle but No Deadlock
• Vertices:
o Threads: T1,T2,T3,T4
o Resources: R1,R2
• Edges:
o T1→R1: Thread T1 requests resource R1
o T1→R2: Thread T1 requests resource R2
o T2→R1: Thread T2 requests resource R1
o T3→R1: Thread T3 requests resource R1
o T3→R2: Thread T3requests resource R2
o T4→R2: Thread T4 requests resource R2
• Cycle:
o T1→R1→T3→R2→T1
• No Deadlock Explanation:
o Even though there is a cycle, there are enough instances of resources R1 and R2
to satisfy the requests. Thus, no thread is blocked indefinitely.
Summary:
49
o Deadlock Prevention: Use methods to ensure that at least one of the necessary
conditions for deadlock (like mutual exclusion, hold and wait, no preemption, or
circular wait) cannot hold. This is discussed in more detail in Section 8.5.
o Deadlock Avoidance: The system requires extra information in advance about which
resources a thread will request and use during its lifetime. With this information, the
system can decide whether to grant or delay each request to avoid deadlock.
3. Detect and Recover from Deadlocks:
o Allow the system to enter a deadlocked state, detect it, and then recover.
o This approach is used by some systems, such as databases.
o If there are no algorithms to detect and recover from deadlocks, the system may enter
a state where performance deteriorates as resources are held by threads that cannot
proceed, leading to more threads becoming deadlocked. Eventually, the system may
stop functioning and need a manual restart.
By using these methods, systems can manage and mitigate the effects of deadlocks to ensure
smooth operation.
• Condition: A thread holds at least one resource and waits to acquire additional resources.
• Prevention:
o Protocol 1: Require threads to request and be allocated all their resources before starting
execution.
o Protocol 2: Allow threads to request resources only when they hold no other resources.
• Limitations:
o Resource utilization may be low because resources might be held for a long time without
being used.
o Starvation can occur if a thread needs several popular resources and has to wait
indefinitely.
50
8.5.3 No Preemption
• Condition: Resources cannot be forcibly taken away from a thread once they have been
allocated.
• Prevention:
o If a thread holding resources requests another resource and must wait, preempt all its
currently held resources.
o Allocate resources only if they are available or can be preempted from other waiting
threads.
• Limitations:
o This protocol works well with resources that can be easily saved and restored, like CPU
registers.
o It is less effective for resources like mutex locks and semaphores, where deadlocks are
more common.
• Condition: A circular chain of threads exists, where each thread holds at least one resource
needed by the next thread in the chain.
• Prevention:
o Assign a unique number to each resource.
o Ensure that threads request resources in an increasing order of these numbers.
o For example, if a thread wants to use both the first and second mutex, it must request the
first mutex before the second mutex.
o Alternatively, a thread can request resources only if it does not hold any resources with a
lower or equal number.
• Result: These protocols prevent the circular-wait condition, thereby avoiding deadlocks.
By using these methods, we can prevent deadlocks and ensure the system runs smoothly.
• Basic Idea: The system knows in advance the order in which threads will request and release
resources.
• Example: If the system knows that Thread P will request Resource R1 first and then R2, while
Thread Q will request R2 first and then R1, it can make decisions to avoid deadlocks.
• Decision Making: The system decides whether a thread should wait based on current and future
resource requests and allocations.
• Definition: A state is safe if the system can allocate resources to each thread in some
order without causing a deadlock.
51
• Safe Sequence: A sequence of threads is safe if each thread can get the resources it
needs, either immediately or after some other threads have finished and released their
resources.
• Example:
o Suppose there are 12 resources and three threads: T0, T1, and T2.
o T0 may need 10 resources, T1 may need 4, and T2 may need 9.
o At a certain time, T0 holds 5 resources, T1 holds 2, and T2 holds 2, leaving 3 free
resources.
o The sequence <T1, T0, T2> is safe because:
▪ T1 can get all its needed resources and then release them.
▪ T0 can then get all its needed resources and release them.
▪ Finally, T2 can get all its needed resources.
• Transition from Safe to Unsafe:
o If T2 requests one more resource and is granted, the system might enter an unsafe
state.
o In this unsafe state, only T1 can be allocated all its resources. If T0 or T2 then request
more resources, it could lead to a deadlock.
• Prevention:
o Ensure the system remains in a safe state by only granting resource requests that keep
the state safe.
o This may cause some threads to wait, reducing resource utilization but avoiding
deadlocks.
• Graph Concept:
o Use a resource-allocation graph to represent resource requests and assignments.
o Introduce "claim edges" (dashed lines) to show potential future resource requests.
• Edge Types:
o Claim Edge: Indicates a thread may request a resource in the future (dashed line).
o Request Edge: Shows a thread is currently requesting a resource.
o Assignment Edge: Shows a resource is currently allocated to a thread.
• Safety Check:
o When a thread requests a resource, convert the claim edge to a request edge.
o Check for cycles in the graph using a cycle-detection algorithm.
o If converting the edge results in no cycles, the request is granted, keeping the state safe.
o If a cycle is detected, the request is denied, and the thread must wait.
• Cycle Detection:
o Detecting a cycle in the graph involves checking for paths and requires operations
proportional to the number of threads squared (n²).
52
By using these methods, we can ensure the system remains in a state where deadlocks are
avoided
Deadlock Detection:
In systems that do not use deadlock prevention or avoidance techniques, deadlocks can occur. To
handle deadlocks, the system can:
There are different approaches depending on whether resources have a single instance or
multiple instances.
For resources with only one instance, a special graph called a wait-for graph is used.
• Wait-for Graph: Derived from the resource-allocation graph by removing resource nodes. If T1
is waiting for a resource held by T2, it will show as an edge from T1 to T2.
• Deadlock Detection: If the wait-for graph has a cycle, a deadlock exists. The system periodically
checks for cycles in this graph.
The algorithm to find a cycle in a graph runs in O(n2) time, where n is the number of vertices.
For example, tools like the BCC toolkit can detect potential deadlocks by tracing calls to mutex
locks and constructing wait-for graphs.
For resources with multiple instances, a different approach is used, similar to the banker's
algorithm.
53
• Data Structures:
o Available: Vector showing available resources.
o Allocation: Matrix showing currently allocated resources to each thread.
o Request: Matrix showing current requests of each thread.
• Detection Algorithm:
1. Initialize Work (available resources) and Finish (threads that can finish).
2. Find a thread that can get all its requested resources (Request[i] <= Work).
3. If found, allocate resources to this thread (Work = Work + Allocation[i]) and mark it as
finished.
4. Repeat until no more threads can be satisfied. If any thread is left unfinished, a deadlock exists.
The algorithm runs in O(m×n2) time, where m is the number of resource types and n is the
number of threads.
Example: Suppose we have 5 threads and 3 resource types with the following state:
• Resources:
o A has 7 instances.
o B has 2 instances.
o C has 6 instances.
• Snapshot:
o Allocation:
▪ T0: (0, 1, 0)
▪ T1: (2, 0, 0)
▪ T2: (3, 0, 3)
▪ T3: (2, 1, 1)
▪ T4: (0, 0, 2)
o Request:
▪ T0: (0, 0, 0)
▪ T1: (2, 0, 2)
▪ T2: (0, 0, 0)
▪ T3: (1, 0, 0)
▪ T4: (0, 0, 2)
By running the detection algorithm, we find that the sequence <T0, T2, T3, T1, T4> allows
all threads to finish, meaning no deadlock.
54
If deadlocks are frequent, the detection algorithm should be run frequently. Running it every
time a resource request is denied is costly, so it might be run periodically, like once an hour or
when CPU utilization drops.
In summary, the detection approach varies based on whether resources have a single instance or
multiple instances, and different algorithms and tools can help detect and handle deadlocks
efficiently.
1. Terminate Processes/Threads
2. Preempt Resources
1. Abort All Deadlocked Processes: This guarantees that the deadlock is broken but can be very
costly, as all progress made by these processes is lost.
2. Abort One Process at a Time: This method aborts processes one by one until the deadlock is
resolved. After each termination, the system checks if the deadlock still exists. This approach
incurs significant overhead.
• Process priority
• How long the process has run and how much longer it needs
• Number and type of resources used
• Number of resources still needed
• How many processes need to be terminated
Resource Preemption
1. Selecting a Victim: Decide which resources and processes to preempt. This decision
should minimize costs, considering factors like the number of resources held and the time
consumed by the process.
2. Rollback: If a resource is taken from a process, the process must be rolled back to a safe
state and restarted. The simplest way is to completely restart the process, although partial
rollbacks (only as far as needed to break the deadlock) are more efficient but require
more information about the process state.
55
3. Starvation: Ensure that the same process is not always chosen as the victim, leading to
starvation (never finishing its task). To prevent this, include the number of rollbacks in
the cost factor for victim selection.
By addressing these issues, the system can effectively recover from deadlocks without leading to
excessive costs or process starvation.
CHP 9
There are various memory management strategies, from simple approaches to complex ones like
paging. The choice of strategy depends on the system's hardware.
• Main Memory and Registers: The only storage directly accessible by the CPU.
• Cache: Fast memory between the CPU and main memory to reduce delays caused by frequent
memory access.
• Compile Time: If the memory location is known during compilation, absolute code is generated.
If the location changes, recompilation is needed.
• Load Time: If the memory location is unknown at compile time, relocatable code is generated.
Binding occurs when loading into memory.
• Execution Time: If a process can move during execution, binding happens at runtime using special
hardware.
56
Logical vs. Physical Address Space (Section 9.1.3)
Summary
Understanding these concepts helps in managing how programs are processed, executed, and
how memory is efficiently utilized in a computer system.
Dynamic loading allows parts of a program to be loaded into memory only when needed, instead
of loading the entire program at once.
• Process:
1. The main program is loaded and starts executing.
57
2. When a routine is called, the program checks if it is already in memory.
3. If not, the routine is loaded from disk, addresses are updated, and execution continues.
• Advantage:
1. Saves memory by only loading necessary routines.
2. Useful for large programs with infrequently used code, like error handling routines.
Dynamic linking allows shared libraries (DLLs) to be linked to programs at runtime, not at
compile time.
• Static Linking:
o Libraries are combined with the program during compile time.
o Increases the size of the binary program image.
• Dynamic Linking:
o Libraries are linked during execution (runtime).
o Saves memory and disk space by sharing common libraries among multiple programs.
Summary
Dynamic loading and dynamic linking optimize memory usage and disk space, ensuring that
only necessary code is loaded and shared libraries are efficiently utilized.
Memory is divided into two main partitions: one for the operating system and one for user
processes. In many systems, including Linux and Windows, the OS is placed in high memory.
Memory allocation involves assigning processes to partitions in memory. Initially, all memory is
available and considered a single large block (hole). Processes are allocated to these holes using
various strategies:
• First Fit: Allocate the first hole large enough to accommodate the process.
• Best Fit: Allocate the smallest hole that is still large enough.
• Worst Fit: Allocate the largest available hole.
58
Simulations show that first fit and best fit are generally more efficient than worst fit.
External Fragmentation:
• Occurs when there is enough total memory to satisfy a request, but the available spaces are not
contiguous, resulting in many small holes.
• Example: Free memory scattered between processes.
Internal Fragmentation:
• Occurs when allocated memory is slightly larger than the requested memory, leaving small,
unused spaces within the allocated block.
Solution to Fragmentation:
• Compaction: Reorganize memory contents to consolidate free memory into a single large block.
• Temporarily moves a process or a portion of a process from main memory to a backing store
(secondary storage) and then brings it back into memory for execution (see Figure 9.19).
• Allows the total physical address space of all processes to exceed the system's physical memory,
increasing the degree of multiprogramming.
• Process: Moves entire processes between main memory and the backing store.
• Backing Store: Fast secondary storage large enough to hold parts of processes that need to be
swapped.
• Procedure: When swapping out, the OS writes process data structures and metadata to the
backing store. For multithreaded processes, per-thread data structures must also be swapped.
59
• Advantage: Enables physical memory to be oversubscribed, accommodating more processes
than the available physical memory.
Virtual memory is a memory management technique that allows the execution of processes
without requiring the entire process to be in physical memory. Here’s a concise breakdown:
Practical Examples
Paging:
• A memory management scheme that allows a process's physical address space to be non-
contiguous.
• Advantages: Avoids external fragmentation and the need for compaction.
Address Translation
61