INDEX
[Link] DATE NAME OF THE PROGRAM PAGE SIGN OF THE
NO. FACULTY
1 Write a program using
System calls.
2 Write a program to
simulate FCFS Algorithm.
3 Write a program to
simulate SJF Algorithm.
4 Write a program to
simulate Round Robin
Algorithm.
5 Write a program to
simulate FIFO page
replacement Algorithm.
6 Write a program to
implement Producer
Consumer using semaphore.
7 Write a program to
simulate Deadlock
Detection.
8 Write a program to
implement Paging Memory
Management.
9 Write a program to
implement File Allocation
Technique.
10 UNIX Commands
1
1) Write a program using System calls.
System Calls:
System calls are the essential interface allowing user
programs to request services from the operating system's
kernel, like file access, process control, or hardware
management, by switching from user mode to the more
privileged kernel mode to execute protected tasks, ensuring
security and resource management.
How They Work
1. Request: A user program needs an OS service
(e.g., open(), read(), fork()).
2. Trap/Interrupt: The program executes a special
instruction (like syscall or int 0x80) to trigger a
trap.
3. Mode Switch: The CPU switches from user mode (limited
privileges) to kernel mode (full privileges).
4. Kernel Execution: The kernel identifies the system call
number, performs the requested operation (e.g., disk
access, memory allocation).
5. Return: The kernel switches back to user mode and returns
the result (data, success/failure) to the program.
Key Functions & Types
• Process
Control: fork(), exec(), exit(), wait() (create/termina
te processes).
• File Management: open(), read(), write(), close() (file
operations).
2
• Device Management: read(), write() (interact with
devices like printers, cameras).
• Information
Maintenance: gettimeofday(), set_pid() (get/set system
info).
• Communication: pipe(), socket() (inter-process
communication).
Why They're Important
• Abstraction: Hide complex hardware details from
applications.
• Security: Protect system resources by enforcing kernel-
level control.
• Portability: Provide a consistent interface across
different hardware.
• Resource Management: Allow the OS to manage shared
resources efficiently.
3
PROGRAM:
CREATE SYSTEM CALL
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
// Create a new file or open it
//if it exists (write-only access)
// File permissions: rw-r--r--
int fd = creat("[Link]", 0644);
if (fd == -1) {
perror("Error creating file");
return 1;
// File was successfully created
printf("File '[Link]' created successfully \n"
"File descriptor: %d\n", fd);
// Close the file descriptor
close(fd);
return 0;
4
OUTPUT:
File '[Link]' created successfully
File descriptor: 3
5
OPEN SYSTEM CALL
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
extern int errno;
int main() {
// If file does not have in directory
// then file [Link] is created.
int fd = open("[Link]", O_RDONLY | O_CREAT);
printf("fd = %d\n", fd);
if (fd == -1) {
// Print which type of error have in a code
printf("Error Number % d\n", errno);
// print program detail "Success or failure"
perror("Program");
return 0;
6
OUTPUT:
fd = 3
7
CLOSE SYSTEM CALL
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int fd1 = open("[Link]", O_RDONLY);
if (fd1 < 0) {
perror("c1");
exit(1);
printf("opened the fd = % d\n", fd1);
// Using close system Call
if (close(fd1) < 0) {
perror("c1");
exit(1);
printf("closed the fd.\n");
8
OUTPUT:
opened the fd = 3
closed the fd.
9
2) Write a program to simulate FCFS Algorithm.
FCFS - First Come First Serve CPU Scheduling
First Come, First Serve (FCFS) is one of the simplest types
of CPU scheduling algorithms. It is exactly what it sounds
like: processes are attended to in the order in which they
arrive in the ready queue, much like customers lining up at
a grocery store.
FCFS Scheduling is a non-preemptive algorithm, meaning once
a process starts running, it cannot be stopped until it
voluntarily relinquishes the CPU, typically when it
terminates or performs I/O. This method schedules processes
in the order they arrive, without considering priority or
other factors.
How Does FCFS Work?
The mechanics of FCFS are straightforward:
1. Arrival: Processes enter the system and are placed in a
queue in the order they arrive.
2. Execution: The CPU takes the first process from the front
of the queue, executes it until it is complete, and then
removes it from the queue.
3. Repeat: The CPU takes the next process in the queue and
repeats the execution process.
This continues until there are no more processes left in the
queue.
Advantages of FCFS
• The simplest and basic form of CPU Scheduling algorithm
• Every process gets a chance to execute in the order of
its arrival. This ensures that no process is arbitrarily
prioritized over another.
10
• Easy to implement, it doesn't require complex data
structures.
• Since processes are executed in the order they arrive,
there’s no risk of starvation
• It is well suited for batch systems where the longer
time periods for each process are often acceptable.
Disadvantages of FCFS
• As it is a Non-preemptive CPU Scheduling Algorithm, FCFS
can result in long waiting times, especially if a long
process arrives before a shorter one. This is known as
the convoy effect, where shorter processes are forced to
wait behind longer processes, leading to inefficient
execution.
• The average waiting time in the FCFS is much higher than
in the others
• Since FCFS processes tasks in the order they arrive,
short jobs may have to wait a long time if they arrive
after longer tasks, which leads to poor performance in
systems with a mix of long and short tasks.
• Processes that are at the end of the queue, have to wait
longer to finish.
• It is not suitable for time-sharing operating systems
where each process should get the same amount of CPU
time.
11
Example of FCFS CPU Scheduling
Consider the following table of arrival time and burst time
for three processes P1, P2 and P3
Process Arrival Time Burst Time
p1 0 5
p2 0 3
p3 0 8
Turnaround Time = Completion Time - Arrival Time
Waiting Time = Turnaround Time - Burst Time
AT : Arrival Time
BT : Burst Time or CPU Time
TAT : Turn Around Time
WT : Waiting Time
Processes AT BT CT TAT WT
P1 0 5 5 5-0 = 5 5-5 = 0
P2 0 3 8 8-0 = 8 8-3 = 5
16-0 = 16-8 =
P3 0 8 16
16 8
• Average Turn around time = 9.67
• Average waiting time = 4.33
12
PROGRAM:
// C program for implementation of FCFS
#include<stdio.h>
// Function to find the waiting time for all
// processes
void findWaitingTime(int processes[], int n,
int bt[], int wt[])
// waiting time for first process is 0
wt[0] = 0;
// calculating waiting time
for (int i = 1; i < n ; i++ )
wt[i] = bt[i-1] + wt[i-1] ;
// Function to calculate turn around time
void findTurnAroundTime( int processes[], int n,
int bt[], int wt[], int tat[])
// calculating turnaround time by adding
// bt[i] + wt[i]
for (int i = 0; i < n ; i++)
tat[i] = bt[i] + wt[i];
//Function to calculate average time
void findavgTime( int processes[], int n, int bt[])
int wt[n], tat[n], total_wt = 0, total_tat = 0;
//Function to find waiting time of all processes
findWaitingTime(processes, n, bt, wt);
13
//Function to find turn around time for all processes
findTurnAroundTime(processes, n, bt, wt, tat);
//Display processes along with all details
printf("Processes Burst time Waiting time Turn around
time\n");
// Calculate total waiting time and total turn
// around time
for (int i=0; i<n; i++)
total_wt = total_wt + wt[i];
total_tat = total_tat + tat[i];
printf(" %d ",(i+1));
printf(" \t %d ", bt[i] );
printf(" \t %d",wt[i] );
printf(" \t %d\n",tat[i] );
float s=(float)total_wt / (float)n;
float t=(float)total_tat / (float)n;
printf("Average waiting time = %f",s);
printf("\n");
printf("Average turn around time = %f ",t);
// Driver code
int main()
//process id's
int processes[] = { 1, 2, 3};
int n = sizeof processes / sizeof processes[0];
14
//Burst time of all processes
int burst_time[] = {5, 3, 8};
findavgTime(processes, n, burst_time);
return 0;
15
OUTPUT:
Processes Burst time Waiting time Turn around time
1 5 0 5
2 3 5 8
3 8 8 16
Average waiting time = 4.333333
Average turn around time = 9.666667
16
3) Write a program to simulate SJF Algorithm.
Shortest Job First or SJF CPU Scheduling
Shortest Job First (SJF) or Shortest Job Next (SJN) is a
scheduling process that selects the waiting process with the
smallest execution time to execute next. This scheduling
method may or may not be preemptive. Significantly reduces
the average waiting time for other processes waiting to be
executed.
Estimation Formula
𝑇𝑛+1 = 𝛼 ⋅ 𝑡𝑛 + (1 − 𝛼) ⋅ 𝑇𝑛
Where:
• Tn+1: Predicted burst time for the next process.
• Tn: Previously predicted burst time.
• tn: Actual burst time of the previous process.
• α: Smoothing factor (0 ≤ α ≤ 1).
Characteristics of SJF Scheduling
• Shortest Job first has the advantage of having a minimum
average waiting time among all operating system
scheduling algorithms.
• It is associated with each task as a unit of time to
complete.
• It may cause starvation if shorter processes keep
coming. This problem can be solved using the concept
of ageing.
Implementation of SJF Scheduling
• Step 1: Input number of processes and their burst
times (arrival time too, if it’s non-preemptive with
arrivals).
Step 2: Sort processes by burst time (if same, use
17
arrival order).
Step 3: Start with the process having the shortest burst
time.
Step 4: Calculate Completion Time = Start Time + Burst
Time.
Step 5: Calculate Turnaround Time = Completion Time −
Arrival Time.
Step 6: Calculate Waiting Time = Turnaround Time − Burst
Time.
Step 7: Repeat until all processes are completed.
Step 8: Compute average waiting time and turnaround
time.
Step 9: Display completion, waiting, and turnaround
times for each process along with averages.
Advantages of SJF Scheduling
• SJF is better than the First come first serve(FCFS)
algorithm as it reduces the average waiting time.
• SJF is generally used for long term scheduling.
• It is suitable for the jobs running in batches, where
run times are already known.
• SJF is probably optimal in terms of average Turn Around
Time (TAT).
Disadvantages of SJF Scheduling
• SJF may cause very long turn-around times or starvation.
• In SJF job completion time must be known earlier.
• Many times it becomes complicated to predict the length
of the upcoming CPU request.
18
Example:
Consider the following table of arrival time and burst time
for three processes P1, P2 and P3.
Process Burst Time Arrival Time
P1 6 ms 0 ms
P2 8 ms 0 ms
P3 3 ms 0 ms
19
PROGRAM:
#include <stdio.h>
int main()
// Matrix for storing Process Id, Burst
// Time, Average Waiting Time & Average
// Turn Around Time.
int A[100][4];
int i, j, n, total = 0, index, temp;
float avg_wt, avg_tat;
printf("Enter number of process: ");
scanf("%d", &n);
printf("Enter Burst Time:\n");
// User Input Burst Time and alloting Process Id.
for (i = 0; i < n; i++) {
printf("P%d: ", i + 1);
scanf("%d", &A[i][1]);
A[i][0] = i + 1;
// Sorting process according to their Burst Time.
for (i = 0; i < n; i++) {
index = i;
for (j = i + 1; j < n; j++)
if (A[j][1] < A[index][1])
index = j;
temp = A[i][1];
A[i][1] = A[index][1];
A[index][1] = temp;
20
temp = A[i][0];
A[i][0] = A[index][0];
A[index][0] = temp;
A[0][2] = 0;
// Calculation of Waiting Times
for (i = 1; i < n; i++) {
A[i][2] = 0;
for (j = 0; j < i; j++)
A[i][2] += A[j][1];
total += A[i][2];
avg_wt = (float)total / n;
total = 0;
printf("P BT WT TAT\n");
// Calculation of Turn Around Time and printing the
// data.
for (i = 0; i < n; i++) {
A[i][3] = A[i][1] + A[i][2];
total += A[i][3];
printf("P%d %d %d %d\n", A[i][0],
A[i][1], A[i][2], A[i][3]);
avg_tat = (float)total / n;
printf("Average Waiting Time= %f", avg_wt);
printf("\nAverage Turnaround Time= %f", avg_tat);
21
OUTPUT:
Enter number of process: 3
Enter Burst Time:
P1: 6
P2: 8
P3: 3
P BT WT TAT
P3 3 0 3
P1 6 3 9
P2 8 9 17
Average Waiting Time= 4.000000
Average Turnaround Time= 9.666667
22
4) Write a program to simulate Round Robin Algorithm.
Round Robin Algorithm
Round Robin Scheduling is a method used by operating systems
to manage the execution time of multiple processes that are
competing for CPU attention. It is called "round robin"
because the system rotates through all the processes,
allocating each of them a fixed time slice or "quantum",
regardless of their priority.
The primary goal of this scheduling method is to ensure that
all processes are given an equal opportunity to execute,
promoting fairness among tasks.
• Process Arrival: Processes enter the system and are
placed in a queue.
• Time Allocation: Each process is given a certain amount
of CPU time, called a quantum.
• Execution: The process uses the CPU for the allocated
time.
• Rotation: If the process completes within the time, it
leaves the system. If not, it goes back to the end of
the queue.
• Repeat: The CPU continues to cycle through the queue
until all processes are completed.
Advantages of Round Robin Scheduling
• Fairness: Each process gets an equal share of the CPU.
• Simplicity: The algorithm is straightforward and easy to
implement.
• Responsiveness: Round Robin can handle multiple
processes without significant delays, making it ideal
for time-sharing systems.
23
Disadvantages of Round Robin Scheduling:
• Overhead: Switching between processes can lead to high
overhead, especially if the quantum is too small.
• Underutilization: If the quantum is too large, it can
cause the CPU to feel unresponsive as it waits for a
process to finish its time.
Example
Processes with Same Arrival Time
• Consider the following table of arrival time and burst
time for three processes P1, P2 and P3 and given Time
Quantum = 2 ms
Process Burst Time Arrival Time
P1 4 ms 0 ms
P2 5 ms 0 ms
P3 3 ms 0 ms
24
PROGRAM:
#include <stdio.h>
void main() {
int i, processes, sum = 0, cnt = 0, y, q, wt = 0, tat = 0, at[10],
bt[10], temp[10];
float avg_waitt, avg_turnat;
// Input the number of processes
printf("Total number of processes in the system: ");
scanf("%d", &processes);
y = processes; // Assign number of processes to y
// Input arrival time and burst time for each process
for(i = 0; i < processes; i++) {
printf("\nEnter the Arrival and Burst time of Process[%d]\n", i
+ 1);
printf("Arrival time: ");
scanf("%d", &at[i]);
printf("Burst time: ");
scanf("%d", &bt[i]);
temp[i] = bt[i]; // Initialize remaining burst time
// Input the time quantum
printf("Enter the Time Quantum: ");
scanf("%d", &q);
// Display header for the process info
printf("\nProcess No \tBurst Time \tTAT \t\tWaiting Time\n");
// Scheduling loop
for(sum = 0, i = 0; y != 0;) {
if(temp[i] <= q && temp[i] > 0) {
25
sum = sum + temp[i];
temp[i] = 0;
cnt = 1;
} else if(temp[i] > 0) {
temp[i] = temp[i] - q;
sum = sum + q;
if(temp[i] == 0 && cnt == 1) {
y--;
printf("\nProcess No[%d] \t%d \t\t%d \t\t%d", i + 1, bt[i],
sum - at[i], sum - at[i] - bt[i]);
wt = wt + sum - at[i] - bt[i];
tat = tat + sum - at[i];
cnt = 0;
if(i == processes - 1) {
i = 0;
} else if(at[i + 1] <= sum) {
i++;
} else {
i = 0;
// Calculate average waiting time and turnaround time
avg_waitt = wt * 1.0 / processes;
avg_turnat = tat * 1.0 / processes;
printf("\n\n Average Turnaround Time: %f", avg_turnat);
printf("\nAverage Waiting Time: %f", avg_waitt);
26
OUTPUT:
Total number of processes in the system: 3
Enter the Arrival and Burst time of Process[1]
Arrival time: 0
Burst time: 4
Enter the Arrival and Burst time of Process[2]
Arrival time: 0
Burst time: 5
Enter the Arrival and Burst time of Process[3]
Arrival time: 0
Burst time: 3
Enter the Time Quantum: 2
Process No Burst Time TAT Waiting Time
Process No[1] 4 8 4
Process No[3] 3 11 8
Process No[2] 5 12 7
Average Turnaround Time: 10.333333
Average Waiting Time: 6.333333
27
5) Write a program to simulate FIFO page replacement
Algorithm.
FIFO page replacement Algorithm:
Page Replacement Algorithms are needed to decide which page
needed to be replaced when new page comes in.
Whenever a new page is referred and not present in
memory, page fault occurs and Operating System replaces one
of the existing pages with newly needed page.
Different page replacement algorithms suggest different ways
to decide which page to replace. The target for all algorithms
is to reduce number of page faults.
First In First Out (FIFO) page replacement algorithm:
This is the simplest page replacement algorithm. In this
algorithm, operating system keeps track of all pages in the
memory in a queue, oldest page is in the front of the queue.
When a page needs to be replaced page in the front of the
queue is selected for removal.
Implementation - Let capacity be the number of pages that
memory can hold. Let set be the current set of pages in
memory.
1. Start traversing the pages.
i) If set holds less pages than capacity.
a) Insert page into the set one by one until
the size of set reaches capacity or all
page requests are processed.
b) Simultaneously maintain the pages in the
queue to perform FIFO.
c) Increment page fault
ii) Else
If current page is present in set, do nothing.
28
Else
a) Remove the first page from the queue
as it was the first to be entered in
the memory
b) Replace the first page in the queue with
the current page in the string.
c) Store current page in the queue.
d) Increment page faults.
2. Return page faults.
29
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
int main() {
int incomingStream[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0,
1, 7, 0, 1}; // Example page reference string
int pages = sizeof(incomingStream) / sizeof(incomingStream[0]);
int frames = 3; // Number of available page frames
int temp[frames];
int pageFaults = 0;
int m, n, s;
for (m = 0; m < frames; m++) {
temp[m] = -1;
printf("Incoming\tFrame 1\t\tFrame 2\t\tFrame 3\n");
for (m = 0; m < pages; m++) {
s = 0;
for (n = 0; n < frames; n++) {
if (incomingStream[m] == temp[n]) {
s++;
pageFaults--;
pageFaults++;
30
if ((pageFaults <= frames) && (s == 0)) {
int i = 0;
while (temp[i] != -1) {
i++;
temp[i] = incomingStream[m];
} else if (s == 0) {
temp[(pageFaults - 1) % frames] = incomingStream[m];
printf("%d\t\t", incomingStream[m]);
for (n = 0; n < frames; n++) {
if (temp[n] != -1) {
printf("%d\t\t", temp[n]);
} else {
printf("-\t\t");
printf("\n");
printf("\nTotal Page Faults:\t%d\n", pageFaults);
return 0;
31
OUTPUT:
Incoming Frame 1 Frame 2 Frame 3
7 7 - -
0 7 0 -
1 7 0 1
2 2 0 1
0 2 0 1
3 2 3 1
0 2 3 0
4 4 3 0
2 4 2 0
3 4 2 3
0 0 2 3
3 0 2 3
2 0 2 3
1 0 1 3
2 0 1 2
0 0 1 2
1 0 1 2
7 7 1 2
0 7 0 2
1 7 0 1
Total Page Faults: 15
32
6) Write a program to implement Producer Consumer using
semaphore.
Producer Consumer Solution using Semaphores
The Producer-Consumer problem is a classic example of a
synchronization problem in operating systems. It demonstrates
how processes or threads can safely share resources without
conflicts. This problem belongs to the process
synchronization domain, specifically dealing with
coordination between multiple processes sharing a common
buffer.
In this problem, we have:
• Producers: Generate data items and place them in a shared
buffer.
• Consumers: Remove and process data items from the buffer.
The main challenge is to ensure:
1. A producer does not add data to a full buffer.
2. A consumer does not remove data from an empty buffer.
3. Multiple producers and consumers do not access the buffer
simultaneously, preventing race conditions.
Semaphore: The Synchronization Tool
A semaphore is an integer-based signaling mechanism used to
coordinate access to shared resources. It supports two atomic
operations:
• wait(S): Decreases the semaphore value by 1. If the value
is ≤0, the process waits.
• signal(S): Increases the semaphore value by 1,
potentially unblocking waiting processes.
Problem Statement
33
Consider a fixed-size buffer shared between a producer and a
consumer.
• The producer generates an item and places it in the
buffer.
• The consumer removes an item from the buffer.
The buffer is the critical section. At any moment:
• A producer cannot place an item if the buffer is full.
• A consumer cannot remove an item if the buffer is empty.
To manage this, we use three semaphores:
• mutex – ensures mutual exclusion when accessing the
buffer.
• full – counts the number of filled slots in the buffer.
• empty – counts the number of empty slots in the buffer.
34
PROGRAM:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int in = 0, out = 0, count = 0;
pthread_mutex_t mutex;
pthread_cond_t not_full;
pthread_cond_t not_empty;
// Producer function
void* producer(void* arg) {
while (1) {
int item = rand() % 100; // produce an item
pthread_mutex_lock(&mutex);
while (count == BUFFER_SIZE) // buffer full
pthread_cond_wait(¬_full, &mutex);
buffer[in] = item;
printf("Produced: %d at %d\n", item, in);
in = (in + 1) % BUFFER_SIZE;
35
count++;
pthread_cond_signal(¬_empty); // signal buffer has item
pthread_mutex_unlock(&mutex);
sleep(1); // simulate production time
return NULL;
// Consumer function
void* consumer(void* arg) {
while (1) {
pthread_mutex_lock(&mutex);
while (count == 0) // buffer empty
pthread_cond_wait(¬_empty, &mutex);
int item = buffer[out];
printf("Consumed: %d at %d\n", item, out);
out = (out + 1) % BUFFER_SIZE;
count--;
pthread_cond_signal(¬_full); // signal buffer has space
pthread_mutex_unlock(&mutex);
sleep(1); // simulate consumption time
36
return NULL;
int main() {
pthread_t prod, cons;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(¬_full, NULL);
pthread_cond_init(¬_empty, NULL);
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(¬_full);
pthread_cond_destroy(¬_empty);
return 0;
37
OUTPUT:
Produced: 83 at 0
Consumed: 83 at 0
Produced: 86 at 1
Consumed: 86 at 1
Produced: 77 at 2
Consumed: 77 at 2
Produced: 15 at 3
Consumed: 15 at 3
Produced: 93 at 4
Consumed: 93 at 4
Produced: 35 at 0
Consumed: 35 at 0
Produced: 86 at 1
Consumed: 86 at 1
Produced: 92 at 2
Consumed: 92 at 2
Produced: 49 at 3
Consumed: 49 at 3
Produced: 21 at 4
Consumed: 21 at 4
Produced: 62 at 0
Consumed: 62 at 0
And so on…
38
7) Write a program to simulate Deadlock Detection.
Deadlock Detection:
In operating systems, managing resources like memory, files,
and processors is very important. Sometimes, processes (or
programs) get stuck waiting for each other to release
resources, leading to a situation called a deadlock. To handle
deadlocks, operating systems use special methods called
deadlock detection algorithms. These algorithms help identify
when a deadlock has happened so that the system can fix the
problem. This is different from methods that try to prevent
deadlocks from happening at all, which can be more
restrictive.
Deadlock Detection Algorithm:
A deadlock detection algorithm is a technique used by an
operating system to identify deadlocks in the system. This
algorithm checks the status of processes and resources to
determine whether any deadlock has occurred and takes
appropriate actions to recover from the deadlock.
Deadlock detection algorithms work by regularly checking the
current state of resource usage in the system. They often use
a visual tool called a resource allocation graph. This graph
shows which processes are using which resources and which
resources each process is waiting for. By looking for cycles
in this graph, the algorithm can spot deadlocks.
Deadlock detection algorithms are vital in operating systems
to prevent processes from getting stuck in a circular wait.
The algorithm employs several times varying data
structures:
• Available: A vector of length m indicates the number of
available resources of each type.
39
• Allocation: An n*m matrix defines the number of
resources of each type currently allocated to a process.
The column represents resource and rows represent a
process.
• Request: An n*m matrix indicates the current request of
each process. If request[i][j] equals k then process
P i is requesting k more instances of resource type R j .
Advantages of Deadlock Detection Algorithms
• Improved System Stability: Deadlocks are a major concern
in operating systems , and detecting and resolving
deadlocks can help to improve the stability of the
system.
• Better Resource Utilization: By detecting deadlocks and
freeing resources, the operating system can ensure that
resources are efficiently utilized and that the system
remains responsive to user requests.
• Easy Implementation: Some deadlock detection algorithms,
such as the Wait-For Graph , are relatively simple to
implement and can be used in a wide range of operating
systems and systems with different resource allocation
and synchronization requirements.
Disadvantages of Deadlock Detection Algorithms
• Performance Overhead: Deadlock detection algorithms can
introduce a significant overhead in terms of
performance, as the system must regularly check for
deadlocks and take appropriate action.
• Complexity: Some deadlock detection algorithms, such as
the Resource Allocation Graph or Timestamping, are more
complex to implement and require a deeper understanding
of the system and its behavior.
40
• False Positives and Negatives: Deadlock detection
algorithms are not perfect and may produce false
positives or negatives, indicating the presence of
deadlocks when they do not exist or failing to detect
deadlocks that do exist.
• Overall, the choice of deadlock detection algorithm
depends on the specific requirements of the system, the
trade-offs between performance, complexity, and
accuracy, and the risk tolerance of the system. The
operating system must balance these factors to ensure
that deadlocks are detected and resolved effectively and
efficiently.
41
PROGRAM:
#include <stdio.h>
int main() {
int n, m, i, j, k;
printf("Enter number of processes: ");
scanf("%d", &n); // Number of processes (P1, P2, ...)
printf("Enter number of resources: ");
scanf("%d", &m); // Number of resource types (R1, R2, ...)
int alloc[10][10], request[10][10], avail[10], work[10], finish[10];
// Input Allocation Matrix
printf("Enter Allocation Matrix (%dx%d):\n", n, m);
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
scanf("%d", &alloc[i][j]);
// Input Request Matrix
printf("Enter Request Matrix (%dx%d):\n", n, m);
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
scanf("%d", &request[i][j]);
// Input Available Resources
printf("Enter Available Resources (%d elements):\n", m);
for (i = 0; i < m; i++)
scanf("%d", &avail[i]);
42
// Initialize Work and Finish vectors
for (i = 0; i < m; i++)
work[i] = avail[i];
for (i = 0; i < n; i++)
finish[i] = 0; // 0 means false
int deadlock = 0;
int can_execute = 1;
while (can_execute) {
can_execute = 0;
for (i = 0; i < n; i++) {
if (finish[i] == 0) {
int possible = 1;
for (j = 0; j < m; j++) {
if (request[i][j] > work[j]) {
possible = 0;
break;
if (possible) {
for (k = 0; k < m; k++)
work[k] += alloc[i][k];
finish[i] = 1;
can_execute = 1;
43
}
// Check for deadlock (any process still not finished)
for (i = 0; i < n; i++) {
if (finish[i] == 0) {
deadlock = 1;
break;
if (deadlock) {
printf("\nSystem is in a DEADLOCKED state. Deadlocked processes:
");
for (i = 0; i < n; i++) {
if (finish[i] == 0) {
printf("P%d ", i);
printf("\n");
} else {
printf("\nSystem is NOT in a deadlocked state.\n");
return 0;
44
OUTPUT:
Enter number of processes: 3
Enter number of resources: 5
Enter Allocation Matrix (3x5):
0 1 0
2 0 0
3 0 3
2 1 1
0 0 2
Enter Request Matrix (3x5):
0 0 0
2 0 2
0 0 0
1 0 0
0 0 2
Enter Available Resources (5 elements):
2 0 2 1 0
System is in a DEADLOCKED state. Deadlocked processes: P0 P1
P2
45
8) Write a program to implement Paging Memory Management.
Paging:
Paging is the process of moving parts of a program, called
pages, from secondary storage into the main memory (RAM). The
main idea behind paging is to break a program into smaller
fixed-size blocks called pages.
• Process does not have to be allocated in a contiguous
memory space.
• The whole process does not have to be in main memory,
some pages can be present, and some pages can be loaded
when needed. It allows more processes and even processes
larger than main memory to run.
• Memory allocation is simplified as memory is always
allocated in fixed sized pages.
Paging in Memory Management
Paging addresses common challenges in allocating and managing
memory efficiently. Why paging is needed as a Memory
Management technique:
• Memory isn’t always available in a single
block: Programs often need more memory than what is
available in a single continuous block. Paging breaks
memory into smaller, fixed-size pieces, making it easier
to allocate scattered free spaces.
• Processes size can increase or decrease programs don’t
need to occupy continuous memory, so they can grow
dynamically without the need to be moved.
Important Features of Paging
• Logical to physical address mapping: Paging divides a
process's logical address space into fixed-size pages.
46
Each page maps to a frame in physical memory, enabling
flexible memory management.
• Fixed page and frame size: Pages and frames have the
same fixed size. This simplifies memory management and
improves system performance.
• Page table entries: Each logical page is represented by
a page table entry (PTE). A PTE stores the corresponding
frame number and control bits.
• Number of page table entries: The page table has one
entry per logical page. Thus, its size equals the number
of pages in the process's address space.
• Page table stored in main memory: The page table is kept
in main memory. This can add overhead when processes are
swapped in or out.
Steps Involved in Paging:
• Step 1 Divide Memory: Logical -> Pages, Physical ->
Frames.
• Step 2 Allocate Pages: Load pages into available
frames.
• Step 3 Page Table: Map logical pages to physical
frames.
• Step 4 Translate Address: Convert logical to physical
address.
• Step 5 Handle Page Fault: Load missing pages from disk.
• Step 6 Run Program: CPU uses page table during
execution.
47
PROGRAM:
#include<stdio.h>
#define MAX 50
int main()
int page[MAX],i,n,f,ps,off,pno;
int choice=0;
printf("\nEnter the no of peges in memory: ");
scanf("%d",&n);
printf("\nEnter page size: ");
scanf("%d",&ps);
printf("\nEnter no of frames: ");
scanf("%d",&f);
for(i=0;i<n;i++)
page[i]=-1;
printf("\nEnter the page table\n");
printf("(Enter frame no as -1 if that page is not present in
any frame)\n\n");
printf("\npageno\tframeno\n-------\t-------");
for(i=0;i<n;i++)
printf("\n\n%d\t\t",i);
scanf("%d",&page[i]);
do
48
{
printf("\n\nEnter the logical address(i.e,page no &
offset):");
scanf("%d%d",&pno,&off);
if(page[pno]==-1)
printf("\n\nThe required page is not available in any of
frames");
else
printf("\n\nPhysical address(i.e,frame no &
offset):%d,%d",page[pno],off);
printf("\nDo you want to continue(1/0)?:");
scanf("%d",&choice);
}while(choice==1);
return 1;
49
OUTPUT:
Enter the no of peges in memory: 3
Enter page size: 5
Enter no of frames: 2
Enter the page table
(Enter frame no as -1 if that page is not present in any
frame)
pageno frameno
------- -------
0 -1
1 2
2 0
Enter the logical address(i.e,page no & offset):12 54
Physical address(i.e,frame no & offset):0,54
Do you want to continue(1/0)?:1
Enter the logical address(i.e,page no & offset):1 4
Physical address(i.e,frame no & offset):2,4
Do you want to continue(1/0)?:0
50
9) Write a program to implement File Allocation Technique.
File Allocation Methods
File allocation methods refer to the strategies employed by
computer operating systems for the efficient distribution of
storage space on disks or other storage media. Their main
objective is to optimize the utilization of available space
and minimize fragmentation, which can impede file access and
decrease the overall performance of the system. There are
several different file allocation methods that are commonly
used, each with its own strengths and weaknesses.
Contiguous File Allocation
In this method, files are stored in a continuous block of
free space on the disk meaning that all the data for a
particular file is stored in one continuous section of the
disk. When a file is created, the operating system searches
for a contiguous block of free space large enough to
accommodate the file. If such a block is found, the file is
stored in that block, and the operating system keeps track
of the starting address and the size of the block.
The advantage of contiguous file allocation is that it
provides fast access to files, as the operating system only
needs to remember the starting address of the file. When a
user requests access to a file, the operating system can
quickly locate the file's starting address and read the
entire file sequentially. This method is particularly useful
for large files, such as video or audio files, which can be
accessed more quickly when stored in contiguous blocks.
However, contiguous file allocation has some limitations.
One significant disadvantage is that it can lead to
fragmentation when files are deleted or when new files are
created. If a file is deleted, the space it occupied becomes
free, but that space may not be contiguous with the
51
remaining free space on the disk. This can result in gaps or
fragments of free space scattered throughout the disk,
making it difficult for the operating system to find
contiguous blocks of free space for new files.
Linked File Allocation
In this method, files are stored in non-contiguous blocks of
free space on the disk, and each block is linked to the next
block using a pointer. When a file is created, the operating
system searches for a series of free blocks that are large
enough to store the file, and it links them together using
pointers. Each block contains the address of the next block
in the file, allowing the operating system to access the
entire file by following the chain of pointers.
The advantage of linked file allocation is that it can
accommodate files of any size, as the file can be stored in
multiple non-contiguous blocks. This method also avoids
fragmentation, as files can be stored in any available free
space on the disk, without the need to find a contiguous
block of free space.
However, linked file allocation has some limitations. One
significant disadvantage is that it can result in slower
access times to files, as the operating system needs to
follow the chain of pointers to access the entire file. This
method may also require more disk space, as each block
contains a pointer to the next block in the file.
Additionally, if a pointer becomes damaged or lost, it can
result in the loss of the entire file, as the operating
system cannot access the entire chain of blocks.
Indexed File Allocation
To address some of the limitations, operating systems can
use a variation of linked file allocation called indexed
file allocation. In indexed file allocation, files are
52
stored in noncontiguous blocks, but instead of linking each
block together, the operating system creates an index block
that contains a list of pointers to each block in the file.
When a file is created, the operating system searches for a
series of free blocks that are large enough to store the
file and creates an index block that contains pointers to
each of those blocks. Each block of the file is then stored
in a separate block on the disk.
The advantage of indexed file allocation is that it provides
fast access to files, as the operating system only needs to
read the index block to locate the file's blocks. This
method also avoids fragmentation, as files can be stored in
any available free space on the disk, without the need to
find a contiguous block of free space. Indexed file
allocation also reduces the risk of data loss, as the index
block can be duplicated to provide redundancy.
However, indexed file allocation has some limitations. One
significant disadvantage is that it can result in wasted
disk space, as the index block can take up a significant
amount of space on the disk. This method also requires more
disk space than linked file allocation, as each block of the
file is stored separately on the disk.
53
PROGRAM:
#include<stdio.h>
#include<stdlib.h> // Required for exit()
// Define a structure to hold file information for the
simulation
struct file {
char fname[10];
int start, size, block[10];
};
void main() {
int i, j, n;
struct file f[10];
printf("Enter no. of files: ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
printf("\nEnter file name: ");
scanf("%s", &f[i].fname);
printf("Enter starting block: ");
scanf("%d", &f[i].start);
f[i].block[0] = f[i].start; // Store the start block
as the first element
54
printf("Enter no. of blocks: ");
scanf("%d", &f[i].size);
printf("Enter block numbers (sequentially as they
would be linked): ");
// Read the subsequent linked block numbers
for (j = 1; j <= f[i].size - 1; j++) {
scanf("%d", &f[i].block[j]);
printf("\nFile\tStart\tSize\tBlock Sequence\n");
for (i = 0; i < n; i++) {
printf("%s\t%d\t%d\t", f[i].fname, f[i].start,
f[i].size);
// Print the linked sequence of blocks
for (j = 0; j <= f[i].size - 2; j++) {
printf("%d--->", f[i].block[j]);
printf("%d", f[i].block[j]); // Print the last block
without the arrow
printf("\n");
55
OUTPUT:
Enter no. of files: 2
Enter file name: Devasish
Enter starting block: 3
Enter no. of blocks: 1
Enter block numbers (sequentially as they would be linked):
Enter file name: Anusha
Enter starting block: 5
Enter no. of blocks: 2
Enter block numbers (sequentially as they would be linked):
File Start Size Block Sequence
Devasish 3 1 3
Anusha 5 2 5--->1
56
10) UNIX COMMANDS?
Unix commands are a set of commands that are used to interact
with the Unix operating system. Unix is a powerful, multi-
user, multi-tasking operating system that was developed in
the 1960s by Bell Labs. Unix commands are entered at the
command prompt in a terminal window, and they allow users to
perform a wide variety of tasks, such as managing files and
directories, running processes, managing user accounts, and
configuring network settings. Unix is now one of the most
commonly used Operating systems used for various purposes
such as Personal use, Servers, Smartphones, and many more. It
was developed in the 1970's at AT& T Labs by two famous
personalities Dennis M. Ritchie and Ken Thompson.
• You'll be surprised to know that the most popular
programming language C came into existence to write the
Unix Operating System.
• Linux is Unix-Like operating system.
• The most important part of the Linux is Linux
Kernel which was first released in the early 90s by Linus
Torvalds. There are several Linux distros available
(most are open-source and free to download and use) such
as Ubuntu, Debian, Fedora, Kali, Mint, Gentoo, Arch and
much more.
• Now coming to the Basic and most usable commands of
Linux/Unix part. (Please note that all the linux/unix
commands are run in the terminal of a linux
[Link] is like command prompt as that of in
Windows OS)
• Linux/Unix commands are case-sensitive i.e Hello is
different from hello.
57
File System Navigation Unix Command
Command Description Example
cd Changes the current working directory. cd Documents
Lists files and directories in the
ls
ls current directory.
Prints the current working directory. pwd
pwd
mkdir
Creates a new directory.
mkdir new_folder
rmdir
Removes an empty directory.
rmdir empty_folder
mv [Link]
Moves files or directories.
mv Documents/
58
File Manipulation Unix Command
Command Description Example
Creates an empty file or updates touch
touch the access and modification times. new_file.txt
cp [Link]
Copies files or directories.
cp [Link]
mv [Link]
Moves files or directories.
mv Documents
rm Remove files or directories. rm old_file.txt
Changes the permissions of a file
chmod 644 [Link]
chmod or directory.
Changes the owner and group of a chown user:group
chown file or directory. [Link]
ln -s target_file
Creates links between files.
ln symlink
Concatenates files and displays cat [Link]
cat their contents. [Link]
Displays the first few lines of a
head [Link]
head file.
59
Command Description Example
Displays the last few lines of a
tail [Link]
tail file.
Displays the contents of a file
more [Link]
more page by page.
Displays the contents of a file
less [Link]
less with advanced navigation features.
diff [Link]
Compares files line by line.
diff [Link]
Applies a diff file to update a patch [Link] <
patch target file. [Link]
60
Process Management Unix Command
Command Description Example
Displays information about active
processes, including their status and ps aux
ps IDs.
Displays a dynamic real-time view of
system processes and their resource top
top usage.
Terminates processes using their process
kill <pid>
kill IDs (PIDs).
Sends signals to processes based on name pkill -9
pkill or other attributes. firefox
killall -9
Terminates processes by name.
killall firefox
Changes the priority of running renice -n
renice processes. 10 <pid>
Runs a command with modified scheduling nice -n 10
nice priority. command
pstree Displays running processes as a tree. pstree
61
Command Description Example
Searches for processes by name or other pgrep
pgrep attributes. firefox
Lists active jobs and their status in
jobs
jobs the current shell session.
bg Puts a job in the background. bg <job_id>
Brings a background job to the
fg <job_id>
fg foreground.
Runs a command immune to hangups, with nohup
nohup output to a specified file. command &
Removes jobs from the shell's job table, disown
disown allowing them to run independently. <job_id>
62
Text Processing Unix Command
Command Description Example
Searches for patterns
grep "error" [Link]
grep in text files.
Processes and sed
transforms text 's/old_string/new_string/g'
sed streams. [Link]
Processes and analyzes
text files using a
awk '{print $1, $3}' [Link]
pattern scanning and
awk processing language.
Network Communication Unix Command
Command Description Example
Tests connectivity
with another host
ping [Link]
using ICMP echo
ping requests.
Traces the route
that packets take to traceroute [Link]
traceroute reach a destination.
63
Command Description Example
Queries DNS servers
for domain name
nslookup [Link]
resolution and IP
nslookup address information.
Performs DNS
queries, providing
dig [Link]
detailed information
dig about DNS records.
Performs DNS
lookups, displaying
host [Link]
domain name to IP
host address resolution.
Retrieves
information about
whois [Link]
domain registration
whois and ownership.
Provides secure
remote access to a ssh username@hostname
ssh system.
Securely copies
scp [Link]
files between hosts
username@hostname:/path/
scp over a network.
64
Command Description Example
Transfers files
between hosts using
ftp hostname
the File Transfer
ftp Protocol (FTP).
Establishes
interactive text-
telnet hostname
based communication
telnet with a remote host.
Displays network
connections, routing
tables, interface
statistics,
netstat -tuln
masquerade
connections, and
multicast
netstat memberships.
Displays or
configures network
ifconfig
interfaces and their
ifconfig settings.
Configures wireless
iwconfig wlan0
iwconfig network interfaces.
65
Command Description Example
Displays or modifies
the IP routing route -n
route table.
Displays or modifies
the Address
arp -a
Resolution Protocol
arp (ARP) cache.
Displays socket
ss -tuln
ss statistics.
Displays or sets the
hostname
hostname system's hostname.
Combines the
functionality of
ping and traceroute,
mtr [Link]
providing detailed
network diagnostic
mtr information.
66
System Administration Unix Command
Command Description Example
df Displays disk space usage. df -h
Displays disk usage of files du -sh
du and directories. /path/to/directory
Manages cron jobs, which are
scheduled tasks that run at crontab -e
crontab -e predefined times or intervals.
Text Editors in Unix
Text Editor Description Example
Vi (Vim) is a highly
configurable, powerful,
Open a file with Vim: vim
and feature-rich text
filename
editor based on the
Exit Vim editor: Press Esc,
original Vi editor. Vim
then type :wq and
offers modes for both
press Enter
command-line operations
Vi / Vim and text editing.
Emacs is a versatile text Open a file with
editor with extensive Emacs: emacs filename
customization Save and exit Emacs:
Emacs
capabilities and support Press Ctrl + X, then Ctrl +
67
Text Editor Description Example
for various programming S and Ctrl + X, then Ctrl +
languages. C to exit
Open a file with Nano: nano
Nano is a simple and user-
filename
friendly text editor
Save and exit Nano:
designed for ease of use
Press Ctrl + O, then Ctrl +
and accessibility.
Nano X
Ed is a standard Unix text
editor that operates in Open a file with Ed: ed
line-oriented mode, filename
making it suitable for Exit Ed editor: Type q and
batch processing and press Enter
Ed automation tasks.
Jed is a lightweight yet
Open a file with Jed: jed
powerful text editor that
filename
provides an intuitive
Save and exit Jed: Press Alt
interface and support for
+ X, then type exit and
various programming
press Enter
Jed languages.
68