OS LAB Manual Periasamy S

Download as pdf or txt
Download as pdf or txt
You are on page 1of 81

HYDERABAD INSTITTE OF TECHNOLOGY AND MANAGEMENT

DEPARTMENT OF EMERGING TECHNOLOGY

Operating Systems
LAB MANUAL

Subject Code : 22PC3CS03


Regulation : R22 / HITAM
Academic Year : 2023-2024
Year & SEM : II Year & II Semester

Prepared by

Periasamy S
Associate Professor
DEPARTMENT OF COMPUTERSCIENCE AND ENGINEERING

PROGRAM EDUCATIONAL OBJECTIVES (PEOS):


A graduate of the Computer Science and Engineering Program should:

Program Educational Objective1: (PEO1)


PEO1
The Graduates will provide solutions to difficult and challenging issues in their profession
by applying computer science and engineering theory and principles.

Program Educational Objective2 :( PEO2)


PEO2
The Graduates have successful careers in computer science and engineering fields or will be able
to successfully pursue advanced degrees.
Program Educational Objective3: (PEO3)
PEO3
The Graduates will communicate effectively, work collaboratively and exhibit high levels
of Professionalism, moral and ethical responsibility.
Program Educational Objective4 :( PEO4)
PEO4
The Graduates will develop the ability to understand and analyse Engineering issues in a
broader perspective with ethical responsibility towards sustainable development.
PROGRAM OUTCOMES (POS):

Engineeringknowledge:Applytheknowledgeofmathematics,science,engineering Fundamentals
PO1 andanengineeringspecializationtothesolutionofcomplexengineeringproblems.
Problem analysis: Identify, formulate, review research literature, and analyze complex engineering
PO2 problems reaching substantiated Conclusions using first principles of
mathematics, natural sciences, and engineering sciences.
Design/development of solutions: Design solutions for complex engineering problems and design
PO3 system components or processes that meet the specified needs with appropriate
consideration for the public health and safety, and the cultural, societal, and environmental
considerations.
Conduct investigations of complex problems: Use research-based knowledge and research methods
PO4 including design of experiments, analysis and interpretation of data, and synthesis of the information
to provide valid conclusions.
Modern tool usage: Create, select, and apply appropriate techniques, resources, and modern
PO5 engineering and IT tools including prediction and modelling to complex engineering activities with an
understanding of the limitations.
The engineer and society: Apply reasoning informed by the contextual knowledge to assess
PO6 societal, health, safety, legal and cultural issues and the consequent responsibilities relevant to the
professional engineering practice.
Environment and sustainability: Understand the impact of the professional engineering Solutions in
PO7 societal and environmental contexts, and demonstrate the knowledge of, and need for sustainable
development.
Ethics: Apply ethical principles and commit to professional ethics and responsibilities and norms
PO8 of the engineering practice.
Individual and team work: Function effectively as an individual, and as a member or leader In
PO9
diverse teams, and in multi-disciplinary settings.
Communication: Communicate effectively on complex engineering activities with the engineering
PO10 community and with society at large, such as, being able to comprehend and write
effective reports and design documentation, make effective presentations, and give and receive clear
instructions.
Project management and finance: Demonstrate knowledge and understanding of the Engineering
PO11 and management principles and apply these to one’s own work, as a member and
leader in a team, to manage projects and in multidisciplinary environments.
Life-long learning: Recognize the need for, and have the preparation and ability to engage in
PO12
independent and life-long learning in the broadest context of technological change.
PROGRAM SPECIFIC OUTCOMES(PSOS):

Problem Solving Skills – Graduate will be able to apply computational techniques and software
PSO1
principles to solve complex engineering problems pertaining to software engineering.
PSO2 Professional Skills – Graduate will be able to think critically, communicate effectively, and
collaborate in teams through participation in co and extra-curricular activities.
Successful Career – Graduates will possess a solid foundation in computer science and
PSO3 engineering that will enable them to grow in their profession and pursue lifelong learning through
post-graduation and professional development.
B. Tech II Year–III Sem L T P C
Subject Code: 22PC3CS17 0 0 2 1

HR22 - Operating Systems Lab


Prerequisites:
A course on “Programming for Problem Solving”.
A course on “Computer Organization and Architecture”.

Course Objectives:
1. To provide an understanding of the design aspects of operating system concepts through Simulation.
2. Introduce basic Unix commands, system call interface for process management, inter process
Communication and I/O in UNIX.

Course Outcomes:
1. Simulate and implement operating system concepts such as scheduling, deadlock management, file
management and memory management.
2. Able to implement C programs using Unix system calls

List of Experiments

1. Write C programs to simulate the following CPU Scheduling algorithms


a) FCFS b) SJF Round Robin d) priority
2. Write a C program to simulate Bankers Algorithm for Deadlock Avoidance and Prevention.
3. Write a C program to implement the Producer – Consumer problem using semaphores.
4. Write a C program to simulate the concept of Dining-philosophers problem.
5. Write C programs to simulate the following memory management techniques
a) Paging b) Segmentation

6. Write C programs to illustrate the following IPC mechanisms


a) Pipes b) FIFOs c) Message Queues d) Shared Memory
7. Write a C program to simulate the following contiguous memory allocation Techniques
a) Worst fit b) Best fit c) First fit
8. Simulate all File Organization Techniques
a) Single level directory b) Two level directory
9. Implementation of the following Page Replacement Algorithms
a) FIFO b) LRU c) LFU
TEXT BOOKS:
1. Operating System Principles , Abraham Silberchatz, Peter B. Galvin, Greg Gagne, 8th Edition,
Wiley Student Edition
2. Operating Systems – Internals and Design Principles, W. Stallings, 6th Edition, Pearson.

REFERENCE BOOKS:
1. Modern Operating Systems, Andrew S Tanenbaum, 3rd Edition, PHI
2. Operating Systems A concept-based Approach, 2nd Edition, D.M.Dhamdhere, TMH.
3. Principles of Operating Systems, B.L.Stuart, Cengage learning, India Edition.

CO-PO &PSO Mapping:

Course Name - Course


Outcomes / Program 1 2 3 4 5 6 7 8 9 10 11 12 PSO1 PSO2 PSO3
Outcomes

CO1 M L

CO2 H H M

CO3 M H

CO4 M L L
EXPERIMENT-1
Write a C program to simulate the following CPU scheduling algorithms:
a)FCFS b)SJF c)Round Robin d)Priority

a)FCFS

DESCRIPTION
Assume all the processes arrive at the same time.

FCFSCPUSCHEDULINGALGORITHM
For FCFS scheduling algorithm, read the number of processes/jobs in the system, their CPU burst
times. The scheduling is performed on the basis of arrival time of the processes irrespective of their
other parameters. Each process will be executed according to its arrival time. Calculate the waiting
time and turnaround time of each of the processes accordingly.

CPUSCHEDULING

Maximum CPU utilization obtained with multiprogramming CPU–


I/O Burst Cycle – Process execution consists of a cycle of CPU
execution and I/O wait
CPU burst distribution
a) First-Come, First-Served (FCFS) Scheduling
Process Burst
Time P1 24
P2 3
P3 3
Suppose that the processes arrive in the order: P1, P2, P3
The Gantt Chart for the schedule is:

0 24 27 30
Waiting time for P1=0;P2=24;P3=27
Average waiting time: (0 + 24 + 27)/3 = 17
ALGORITHM

1. Start
2. Declare the array size
3. Read the number of processes to be inserted
4. Read the Burst times of processes
5. Calculate the waiting time of each process wt[i+1]=bt[i]+wt[i]
6. Calculate the turnaround time of each process tt[i+1]=tt[i]+bt[i+1]
7. Calculate the average waiting time and average turnaround time.
8. Display the values
9. Stop

PROGRAM:

#include<stdio.h>voi
d main()
{
inti,j,bt[10],n,wt[10],tt[10],w1=0,t1=0;
float aw,at;
printf("enter no. of processes:\n");
scanf("%d",&n);
printf("enter the burst time of processes:");
for(i=0;i<n;i++)
scanf("%d",&bt[i]);
for(i=0;i<n;i++)
{
wt[0]=0;
tt[0]=bt[0];
wt[i+1]=bt[i]+wt[i];
tt[i+1]=tt[i]+bt[i+1];
w1=w1+wt[i];
t1=t1+tt[i];
}
aw=w1/n;
at=t1/n;
printf("\nbt\twt\ttt\n");
for(i=0;i<n;i++)
printf("%d\t%d\t%d\n",bt[i],wt[i],tt[i]);
printf("aw=%f\n,at=%f\n",aw,at);
}
INPUT

Enter no of processes
3
Enter burst time
12
8
20

EXPECTEDOUTPUT

btwttt

12012
81220
20 20 40
aw=10.666670
at=24.00000
b) SJF

SJFCPUSCHEDULINGALGORITHM
For SJF scheduling algorithm, read the number of processes/jobs in the system, their CPU burst
times. Arrange all the jobs in order with respect to their burst times. There may be two jobs in
queue with the same execution time and then FCFS approach is to be performed. Each process will
be executed according to the length of its burst time. Then calculate the waiting time and
turnaround time of each of the processes accordingly.

HARDWARE REQUIREMENTS: Intel based Desktop Pc


RAMof512MB
SOFTWAREREQUIREMENTS:
Turbo C/Borland C.

THEORY:
Example of Non Pre-emptive SJF

Process Arrival Time Burst Time

P1 0.0 7

P2 2.0 4

P3 4.0 1

P4 3.0 4

P1 P3 P2 P4
0 7 8 12 16

Example of Preemptive SJF

Process Arrival Time Burst Time


P1 0.0 7

P2 2.0 4

P3 4.0 1

P4 3.0 4
P1 P2 P3 P2 P4 P1
Average waiting time=(9+1+0+2)/4=3 ALGORITHM

1. Start
2. Declare the array size
3. Read the number of processes to be inserted.
4. Read the Burst times of processes.
5. Sort the Burst times in ascending order, and process with the shortest burst time is first executed.
6. Calculate the waiting time of each process: wt[i+1] = bt[i] + wt[i]
7. Calculate the turnaround time of each process: tt[i+1] = tt[i] + bt[i+1]
8. Calculate the average waiting time and average turnaround time.
9. Display the values.
10. Stop.

PROGRAM:

#include<stdio.h>

void main() {
int i, j, bt[10], t, n, wt[10], tt[10], w1 = 0, t1 = 0;
float aw, at;

printf("Enter the number of processes:\n");


scanf("%d", &n);

printf("Enter the burst time of processes:");


for (i = 0; i < n; i++)
scanf("%d", &bt[i]);

for (i = 0; i < n; i++) {


for (j = i; j < n; j++) {
if (bt[i] > bt[j]) {
t = bt[i];
bt[i] = bt[j];
bt[j] = t;
}
}
}

printf("Sorted burst times: ");


for (i = 0; i < n; i++)
printf("%d ", bt[i]);

wt[0] = 0;
tt[0] = bt[0];
for (i = 0; i < n; i++) {
wt[i + 1] = bt[i] + wt[i];
tt[i + 1] = tt[i] + bt[i + 1];
w1 = w1 + wt[i];
t1 = t1 + tt[i];
}

aw = (float) w1 / n;
at = (float) t1 / n;

printf("\n\nBurst Time\tWaiting Time\tTurnaround Time\n");


for (i = 0; i < n; i++)
printf("%d\t\t%d\t\t%d\n", bt[i], wt[i], tt[i]);

printf("\nAverage waiting time = %f\nAverage turnaround time = %f\n", aw, at);


}

INPUT:
Enter no of processes
3
Enter burs ttime
12
8
20

OUTPUT:
bt wt tt
12 8 20
8 0 8
20 20 40
aw=9.33
at=22.64
c) Round Robin

DESCRIPTION
Assume all the processes arrive at the same time.

ROUNDROBINCPUSCHEDULING ALGORITHM
For round robin scheduling algorithm, read the number of processes/jobs in the system, their CPU
burst times, and the size of the time slice. Time slices are assigned to each process in equal portions
and in circular order, handling all processes execution. This allows every process to get an equal
chance. Calculate the waiting time and turnaround time of each of the processes accordingly.

THEORY:
Round Robin:

Example of RR with time quantum=3

Process Burst time


aaa 4
Bbb 3
Ccc 2
Ddd 5
Eee 1

ALGORITHM
1. Start
2. Declare the array size
3. Read the number of processes to be inserted
4. Read the burst times of the processes
5. Read the Time Quantum
6. If the burst time of a process is greater than Time Quantum, then subtract Time Quantum
from the burst time. Else, assign the burst time to Time Quantum.
7. Calculate the average waiting time and turnaround time of the processes.
8. Display the values
9. Stop

PROGRAM:

#include<stdio.h>
void main() {
int st[10], bt[10], wt[10], tat[10], n, tq;
int i, count = 0, swt = 0, stat = 0, temp, sq = 0;
float awt = 0.0, atat = 0.0;

printf("Enter number of processes:");


scanf("%d", &n);

printf("Enter burst time for sequences:");


for (i = 0; i < n; i++) {
scanf("%d", &bt[i]);
st[i] = bt[i];
}

printf("Enter time quantum:");


scanf("%d", &tq);

while (1) {
for (i = 0, count = 0; i < n; i++) {
temp = tq;
if (st[i] == 0) {
count++;
continue;
}
if (st[i] > tq)
st[i] = st[i] - tq;
else if (st[i] >= 0) {
temp = st[i];
st[i] = 0;
}
sq = sq + temp;
tat[i] = sq;
}
if (n == count)
break;
}

for (i = 0; i < n; i++) {


wt[i] = tat[i] - bt[i];
swt = swt + wt[i];
stat = stat + tat[i];
}

awt = (float)swt / n;
atat = (float)stat / n;

printf("\nProcess_no\tBurst time\tWait time\tTurnaround time");


for (i = 0; i < n; i++)
printf("\n%d\t\t%d\t\t%d\t\t%d", i + 1, bt[i], wt[i], tat[i]);

printf("\nAvg wait time is %f\nAvg turnaround time is %f", awt, atat);


}
Input:
Enter no of jobs
4
Enter burst time
5
12
8
20
Output:

Bt wt tt
505
12513
81325
20 25 45
aw=10.75000
at=22.000000
d) Priority
HARDWAREREQUIREMENTS: Intel based Desktop Pc
RAMof512MB
SOFTWAREREQUIREMENTS:
Turbo C / Borland C.

THEORY:

In Priority Scheduling, each process is given a priority, and higher priority methods are executed first,
while processes with equal priorities are executed using either the First Come First Served or Round
Robin scheduling algorithms.
There are several ways that priorities can be assigned:
Internal priorities are assigned by technical quantities such as memory usage and file/IO operations.
External priorities are assigned by politics, commerce, or user preference, such as importance and the
amount being paid for process access. The latter is usually applicable for mainframes.

ALGORITHM

1. Start
2. Declare the array size
3. Read the number of processes to be inserted
4. Read the Priorities of processes
5. Sort the priorities and Burst times in ascending order
6. Calculate the waiting time of each process: wt[i+1] = bt[i] + wt[i]
7. Calculate the turnaround time of each process: tt[i+1] = tt[i] + bt[i+1]
8. Calculate the average waiting time and average turnaround time.
9. Display the values
10. Stop

PROGRAM:

#include<stdio.h>

void main() {
int i, j, pno[10], prior[10], bt[10], n, wt[10], tt[10], w1 = 0, t1 = 0, s;
float aw, at;

printf("Enter the number of processes:");


scanf("%d", &n);

for (i = 0; i < n; i++) {


printf("Enter the burst time of process %d:", i + 1);
scanf("%d", &bt[i]);
printf("Enter the priority of process %d:", i + 1);
scanf("%d", &prior[i]);
pno[i] = i + 1;
}

for (i = 0; i < n; i++) {


for (j = 0; j < n; j++) {
if (prior[i] < prior[j]) {
s = prior[i];
prior[i] = prior[j];
prior[j] = s;

s = bt[i];
bt[i] = bt[j];
bt[j] = s;

s = pno[i];
pno[i] = pno[j];
pno[j] = s;
}
}
}

for (i = 0; i < n; i++) {


wt[0] = 0;
tt[0] = bt[0];
wt[i + 1] = bt[i] + wt[i];
tt[i + 1] = tt[i] + bt[i + 1];
w1 = w1 + wt[i];
t1 = t1 + tt[i];
aw = (float) w1 / n;
at = (float) t1 / n;
}

printf("\njob\t bt\twt\ttat\tprior\n");
for (i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\t%d\n", pno[i], bt[i], wt[i], tt[i], prior[i]);
printf("Average waiting time = %f \t Average turnaround time = %f \n", aw, at);
}

Input:

Enter no of jobs 4
Enter burst time 10
2
4
7
Enter priority values 4
2
1
3

Output:

Bt priority wt tt 4 1 0 4
2246
73613
10 4 13 23 aw=5.750000 at=12.500000
VIVA QUESTIONS:

1. Round Robin scheduling is used in: (B) CPU scheduling


2. What are the disadvantages of Round Robin Scheduling Algorithm?
3. What are the advantages of Round Robin Scheduling Algorithm?
4. Supercomputers typically employ: (2) Multiprocessors OS
5. An optimal scheduling algorithm in terms of minimizing the average waiting
time of a given set of processes is: (3) Shortest job - first scheduling algorithm
6. The optimum CPU scheduling algorithm is: (C) SJF without pre-emption
7. In terms of average wait time, the optimum scheduling algorithm is: (B) SJF
8. What are the disadvantages of SJF Scheduling Algorithm?
9. What are the advantages of SJF Scheduling Algorithm?
10. Define CPU Scheduling algorithm.
11. What is First-Come-First-Served (FCFS) Scheduling?
12. Why CPU scheduling is required?
13. Which technique was introduced because a single job could not keep both
the CPU and the I/O devices busy? (4) Multiprogramming
14. CPU performance is measured through: (1) Throughput
15. Which of the following is a criterion to evaluate a scheduling algorithm? (1)
CPU Utilization: Keep CPU utilization as high as possible.

EXPERIMENT-2

OBJECTIVE
To implement a C program to simulate Banker's Algorithm for Deadlock Avoidance.

DESCRIPTION
In a multiprogramming environment, several processes may compete for a finite number of resources.
A process requests resources; if the resources are not available at that time, the process enters a
waiting state. Sometimes, a waiting process is never again able to change state because the resources
it has requested are held by other waiting processes. This situation is called a deadlock. Deadlock
avoidance is one of the techniques for handling deadlocks. This approach requires that the operating
system be given in advance additional information concerning which resources a process will request
and use during its lifetime. With this additional knowledge, it can decide for each request whether or
not the process should wait. To decide whether the current request can be satisfied or must be
delayed, the system must consider the resources currently available, the resources currently allocated
to each process, and the future requests and releases of each process.
Banker’s algorithm is a deadlock avoidance algorithm that is applicable to a system with multiple
instances of each resource type.
NAME OF EXPERIMENT
Simulate Banker’s Algorithm for Deadlock Avoidance.

AIM
To simulate Banker’s Algorithm for Deadlock Avoidance to find whether the system is in a safe state
or not.

HARDWARE REQUIREMENTS
Intel-based Desktop PC, RAM of 512 MB.

SOFTWARE REQUIREMENTS
Turbo C/Borland C.

THEORY - DEADLOCK AVOIDANCE

To implement deadlock avoidance & Prevention by using Banker’s Algorithm.

Banker’s Algorithm:

When a new process enters a system, it must declare the maximum number of instances of each
resource type it needs. This number may exceed the total number of resources in the system. When
the user requests a set of resources, the system must determine whether the allocation of each
resource will leave the system in a safe state. If it will, the resources are allocated; otherwise, the
process must wait until some other process releases the resources.

Data structures:

 n: Number of processes, m: Number of resource types.


 Available: Available[j] = k, where k is the number of instances of resource type Rj available.
 Max: If max[i, j] = k, process Pi may request at most k instances of resource Rj.
 Allocation: If Allocation[i, j] = k, process Pi is allocated to k instances of resource Rj.
 Need: If Need[I, j] = k, process Pi may need k more instances of resource type Rj.
Need[I, j] = Max[I, j] - Allocation[I, j].

Safety Algorithm

1. Work and Finish be the vector of length m and n respectively, where Work = Available and
Finish[i] = False.
2. Find an i such that both:
 Finish[i] = False
 Need <= Work If no such i exists, go to step 4.
3. Work = Work + Allocation, Finish[i] = True.
4. If Finish[1] = True for all I, then the system is in a safe state.
Resource request algorithm

Let Request i be the request vector for the process Pi. If Request i[j] = k, then process Pi wants k
instances of resource type Rj.
1. If Request <= Need, go to step 2. Otherwise, raise an error condition.
2. If Request <= Available, go to step 3. Otherwise, Pi must wait since the resources are
unavailable.
3. Have the system pretend to have allocated the requested resources to process Pi by modifying
the state as follows: Available = Available - Request i, Allocation I = Allocation + Request
i, Need i = Need i - Request i. If the resulting resource allocation state is safe, the transaction
is completed, and process Pi is allocated its resources. However, if the state is unsafe, Pi must
wait for Request i, and the old resource-allocation state is restored.
4.
ALGORITHM

1. Start the program.


2. Get the values of resources and processes.
3. Get the avail value.
4. After allocation, find the need value.
5. Check whether it's possible to allocate.
6. If it is possible, then the system is in a safe state.
7. Else the system is not in a safe state.
8. If the new request comes, then check that the system is in safety or not if we allow the request.
9. Stop the program.

PROGRAM:

#include<stdio.h>

struct da {
int max[10], al[10], need[10], before[10], after[10];
} p[10];

void main() {
int i, j, k, l, r, n, tot[10], av[10], cn = 0, cz = 0, temp = 0, c = 0;

printf("\n Enter the number of processes:");


scanf("%d", &n);
printf("\nEnter the number of resources:");
scanf("%d", &r);

for (i = 0; i < n; i++) {


printf("process%d\n", i + 1);
for (j = 0; j < r; j++) {
printf("maximum value for resource %d:", j + 1);
scanf("%d", &p[i].max[j]);
}
for (j = 0; j < r; j++) {
printf("allocated from resource %d:", j + 1);
scanf("%d", &p[i].al[j]);
p[i].need[j] = p[i].max[j] - p[i].al[j];
}
}

for (i = 0; i < r; i++) {


printf("Enter total value of resource %d:", i + 1);
scanf("%d", &tot[i]);
}

for (i = 0; i < r; i++) {


for (j = 0; j < n; j++)
temp = temp + p[j].al[i];
av[i] = tot[i] - temp;
temp = 0;
}

printf("\n\tmax\tallocated\tneeded\ttotal\tavail");
for (i = 0; i < n; i++) {
printf("\n P%d\t", i + 1);
for (j = 0; j < r; j++)
printf("%d\t", p[i].max[j]);
printf("\t");
for (j = 0; j < r; j++)
printf("%d\t", p[i].al[j]);
printf("\t");
for (j = 0; j < r; j++)
printf("%d\t", p[i].need[j]);
printf("\t");
for (j = 0; j < r; j++) {
if (i == 0)
printf("%d", tot[j]);
}
printf("\t");
for (j = 0; j < r; j++) {
if (i == 0)
printf("%d", av[j]);
}
}

printf("\n\n\tAVAILBEFORE\tAVAILAFTER");
for (l = 0; l < n; l++) {
for (i = 0; i < n; i++) {
for (j = 0; j < r; j++) {
if (p[i].need[j] > av[j])
cn++;
if (p[i].max[j] == 0)
cz++;
}
if (cn == 0 && cz != r) {
for (j = 0; j < r; j++) {
p[i].before[j] = av[j] - p[i].need[j];
p[i].after[j] = p[i].before[j] + p[i].max[j];
av[j] = p[i].after[j];
p[i].max[j] = 0;
}
printf("\n P%d\t", i + 1);
for (j = 0; j < r; j++)
printf("%d\t", p[i].before[j]);
printf("\t");
for (j = 0; j < r; j++)
printf("%d\t", p[i].after[j]);
cn = 0;
cz = 0;
c++;
break;
} else {
cn = 0;
cz = 0;
}
}
}
if (c == n)
printf("\nThe above sequence is a safe sequence");
else
printf("\nDeadlock occurred");
}

OUTPUT:

//TESTCASE 1:

ENTERTHE NO.OFPROCESSES:4

ENTER THE NO.OF


FRESOURCES:3 PROCESS 1
MAXIMUM VALUE FOR
RESOURCE1:3
MAXIMUMVALUEFORRES
OURCE2:2
MAXIMUMVALUEFORRES
OURCE3:2 ALLOCATED
FROM RESOURCE 1:1
ALLOCATED FROM
RESOURCE 2:0
ALLOCATED FROM
RESOURCE 3:0 PROCESS 2
MAXIMUMVALUEFORRES
OURCE1:6
MAXIMUMVALUEFORRES
OURCE2:1
MAXIMUMVALUEFORRES
OURCE3:3 ALLOCATED
FROM RESOURCE 1:5
ALLOCATED FROM
RESOURCE 2:1
ALLOCATED FROM
RESOURCE 3:1 PROCESS 3
MAXIMUMVALUEFORRES
OURCE1:3
MAXIMUMVALUEFORRES
OURCE2:1
MAXIMUMVALUEFORRES
OURCE3:4 ALLOCATED
FROM RESOURCE 1:2
ALLOCATED FROM
RESOURCE 2:1
ALLOCATED FROM
RESOURCE 3:1

PROCESS4
MAXIMUM VALUE FOR
RESOURCE 1:4 MAXIMUM
VALUE FOR RESOURCE 2:2
MAXIMUM VALUE FOR
RESOURCE 3:2 ALLOCATED
FROM RESOURCE 1:0
ALLOCATED FROM
RESOURCE 2:0 ALLOCATED
FROM RESOURCE 3:2
ENTERTOTALVALUEOFRES
OURCE1:9
ENTERTOTALVALUEOFRES
OURCE2:3
ENTERTOTALVALUEOFRESOURCE3:6

RESOURCESALLOCATEDNEEDED TOTALAVAIL
P1 322 100 222 936 112
P2 613 511 102
P3 314 211 103
P4 422 002 420

AVAILBEFOREAVAILAFTER
P2 010 623
P1 401 723
P3 620 934
P4 514 936

THEABOVESEQUENCEISASAFE SEQUENCE

VIVA QUESTIONS:

1. Differentiate deadlock avoidance and fragmentation.


2. Tell me the real-time example where this deadlock occurs?
3. How do we calculate the need for a process?
4. What is the name of the algorithm to avoid deadlock?
5. Banker’s algorithm for resource allocation deals with (B) Deadlock avoidance.
6. Each request requires that the system consider the to decide whether the current
request can be satisfied or must wait to avoid a future possible deadlock.
7. Given a priori information about the number of resources of each type that may be
requested for each process, it is possible to construct an algorithm that ensures that the
system will never enter a deadlock state.
8. A deadlock avoidance algorithm dynamically examines the to ensure that a circular
wait condition can never exist.
9. Define Safe State.

1. A system is in a safe state only if there exists a safe sequence.


2. Is it true that all unsafe states are deadlocks?
3. A system has 12 magnetic tape drives and 3 processes: P0, P1, and P2. Process P0
requires 10 tape drives, P1 requires 4, and P2 requires 9 tape drives. Currently allocated
(process-wise): P0 - 5, P1 - 2, P2 - 2. Which of the following sequences is a safe sequence?
a) P0, P1, P2 b) P1, P2, P0 c) P2, P0, P1 d) P1, P0, P2
4. If no cycle exists in the resource allocation graph, then ____.
5. The resource allocation graph is not applicable to a resource allocation system with
____.
6. The Banker’s algorithm is ____ than the resource allocation graph algorithm.
7. List data structures available in the Banker’s algorithm. The data structures available
in the Banker’s algorithm are: a) Available b) Need c) Allocation
8. What is the content of the matrix Need?
9. A system with 5 processes P0 through P4 and three resource types A, B, C has A with
10 instances, B with 5 instances, and C with 7 instances. At time t=0, the following
snapshot has been taken: Process Allocation (P0-P4, top to bottom): ABC 010 200 302 211
002 MAX (P0-P4, top to bottom): ABC 753 322 902 222 433 Available: ABC 332 The
sequence <P1, P3, P4, P2, P0> leads the system to: a) an unsafe state b) a safe state c) a
protected state d) a deadlock
10. The wait-for graph is a deadlock detection algorithm that is applicable when ____.
11. What does an edge from process Pi to Pj in a wait-for graph indicate? Pi is waiting
for Pj to release a resource that Pi needs.
12. If the wait-for graph contains a cycle, ____.
13. If deadlocks occur frequently, the detection algorithm must be invoked ____.
14. The disadvantage of invoking the detection algorithm for every request is ____.
15. 'm' processes share 'n' resources of the same type. The maximum need of each
process doesn’t exceed 'n', and the sum of all their maximum needs is always less than
m+n. In this setup, deadlock ____. a) can never occur b) may occur c) has to occur d) none
of the mentioned
16. A system has 3 processes sharing 4 resources. If each process needs a maximum of 2
units, then deadlock ____. a) can never occur b) may occur c) has to occur d) none of the
mentioned

OBJECTIVE

Write a C program to simulate Bankers algorithm for Dead lock Prevention

DESCRIPTION In a multiprogramming environment, several processes may compete for a


finite number of resources. A process requests resources; if the resources are not available
at that time, the process enters a waiting state. Sometimes, a waiting process is never
again able to change state because the resources it has requested are held by other
waiting processes. This situation is called a deadlock. Deadlock avoidance is one of the
techniques for handling deadlocks. This approach requires that the operating system be
given in advance additional information concerning which resources a process will request
and use during its lifetime. With this additional knowledge, it can decide for each request
whether or not the process should wait. To decide whether the current request can be
satisfied or must be delayed, the system must consider the resources currently available,
the resources currently allocated to each process, and the future requests and releases of
each process.

Banker’s algorithm is a deadlock avoidance algorithm that is applicable to a system with


multiple instances of each resource type.

NAME OF EXPERIMENT: Simulate Algorithm for Deadlock Prevention. AIM: Simulate


Algorithm for Deadlock Prevention.

HARDWARE REQUIREMENTS:

 Intel-based Desktop PC
 RAM of 512MB

SOFTWARE REQUIREMENTS:

 TurboC/Borland C.

THEORY:

Deadlock Definition:

A set of processes is deadlocked if each process in the set is waiting for an event that only
another process in the set can cause (including itself). Waiting for an event could be:

 waiting for access to a critical section


 waiting for a resource. Note that it is usually a non-preemptable resource.

Conditions for Deadlock:

 Mutual exclusion: resources cannot be shared.


 Hold and wait: processes request resources incrementally and hold onto what
they've got.
 No preemption: resources cannot be forcibly taken from processes.
 Circular wait: circular chain of waiting, in which each process is waiting for a resource
held by the next process in the chain.

Strategies for dealing with Deadlock:

 Ignore the problem altogether


 Detection and recovery
 Avoidance by careful resource allocation
 Prevention by structurally negating one of the four necessary conditions.

Deadlock Prevention:

Difference from avoidance is that here, the system itself is built in such a way that there
are no deadlocks. Make sure at least one of the 4 deadlock conditions is never satisfied.
This may, however, be even more conservative than deadlock avoidance strategy.

Algorithm:

1. Start
2. Attacking Mutex condition: never grant exclusive access. But this may not be
possible for several resources.
3. Attacking pre-emption: not something you want to do.
4. Attacking hold and wait condition: make a process hold at the most 1 resource at a
time. Make all the requests at the beginning. All or nothing policy. If you feel, retry. e.g., 2-
phase locking.
5. Attacking circular wait: Order all the resources. Make sure that the requests are
issued in the correct order so that there are no cycles present in the resource graph.
Resources numbered 1...n. Resources can be requested only in increasing order. i.e., you
cannot request a resource whose no is less than any you may be holding.
6. Stop

PROGRAM:
#include <stdio.h>

int max[10][10], alloc[10][10], need[10][10], avail[10];


int i, j, p, r, finish[10] = {0}, flag = 0;

void fun();
int main() {
printf("\n\nSIMULATION OF DEADLOCK PREVENTION");
printf("\nEnter no. of processes, resources: ");
scanf("%d%d", &p, &r);
printf("Enter allocation matrix:\n");
for (i = 0; i < p; i++)
for (j = 0; j < r; j++)
scanf("%d", &alloc[i][j]);
printf("Enter max matrix:\n");
for (i = 0; i < p; i++) /*reading the maximum matrix and available matrix*/
for (j = 0; j < r; j++)
scanf("%d", &max[i][j]);
printf("Enter available matrix:\n");
for (i = 0; i < r; i++)
scanf("%d", &avail[i]);

for (i = 0; i < p; i++)


for (j = 0; j < r; j++)
need[i][j] = max[i][j] - alloc[i][j];
fun(); /*calling function*/
if (flag == 0) {
for (i = 0; i < p; i++) {
if (finish[i] != 1) {
printf("\n\nFailing: Mutual exclusion");
for (j = 0; j < r; j++) {
/*checking for mutual exclusion*/
if (avail[j] < need[i][j])
avail[j] = need[i][j];
}
fun();
printf("\nBy allocating required resources to process %d, deadlock is prevented", i);
printf("\n\nFailing: Lack of preemption");
for (j = 0; j < r; j++) {
if (avail[j] < need[i][j])
avail[j] = need[i][j];
alloc[i][j] = 0;
}
fun();
printf("\nDeadlock is prevented by allocating needed resources");
printf("\n\nFailing: Hold and Wait condition ");
for (j = 0; j < r; j++) {
/*checking hold and wait condition*/
if (avail[j] < need[i][j])
avail[j] = need[i][j];
}
fun();
printf("\nAVOIDING ANYONE OF THE CONDITION, U CAN PREVENT DEADLOCK");
}
}
}
}

void fun() {
while (1) {
for (flag = 0, i = 0; i < p; i++) {
if (finish[i] == 0) {
for (j = 0; j < r; j++) {
if (need[i][j] <= avail[j])
continue;
else
break;
}
if (j == r) {
for (j = 0; j < r; j++)
avail[j] += alloc[i][j];
flag = 1;
finish[i] = 1;
}
}
}
if (flag == 0)
break;
}
}

Output:

SIMULATION OF DEADLOCK PREVENTION


Enter no. of processes,resources3,2 enter allocation
matrix 2 4 5
345
Entermaxmatrix434
561
Enter a variable matrix 2 5
Failing: Mutual Exclusion
By allocating required resources to process dead is prevented
Lack of no0 preemption deadlock is prevented by allocating needed resources
Failing : Hold and Wait condition

VIVA QUESTIONS:
1. The Banker’s algorithm is used for deadlock avoidance.
2. Circular wait is the situation in which a process is waiting on another process, which
is also waiting on another process, and so on, forming a circular chain where none of the
processes involved are making progress.
3. A safe state is a state in which the system can allocate resources to each process in
such a way that no deadlock will occur.
4. The conditions that cause deadlock are mutual exclusion, hold and wait, no
preemption, and circular wait.
5. The need for a process is calculated by subtracting the allocated resources from the
maximum resources required by that process.
6. The number of resources requested by a process must not exceed the total number
of resources available in the system.
7. The request and release of resources are atomic operations.
8. Multithreaded programs are programs that consist of multiple threads of execution
that can run concurrently.
9. For a deadlock to arise, the conditions that must hold simultaneously are mutual
exclusion, no preemption, hold and wait.
10. For mutual exclusion to prevail in the system, at least one resource must be held in a
nonsharable mode.
11. For a Hold and wait condition to prevail, a process must be holding at least one
resource while waiting to acquire additional resources held by other processes.
12. Deadlock prevention is a set of methods to ensure that at least one of the necessary
conditions for deadlock cannot hold.
13. For non-sharable resources like a printer, mutual exclusion must exist.
14. For sharable resources, mutual exclusion is not required.
15. To ensure that the hold and wait condition never occurs in the system, it must be
ensured that each process must request and be allocated all its resources before it begins
its execution (Option b).
16. The disadvantage of a process being allocated all its resources before beginning its
execution is that it may lead to resource underutilization and decreased system
throughput.
17. To ensure deadlock avoidance, if a process is holding some resources and requests
another resource that cannot be immediately allocated to it, then all resources currently
being held by that process are pre-empted.
18. A deadlock can be broken by aborting one or more processes to break the circular
wait.
19. The two ways of aborting processes and eliminating deadlocks are preemptive
process termination and resource preemption.
20. Those processes should be aborted on the occurrence of a deadlock, the
termination of which will lead to the minimum cost to the system.

EXPERIMENT-3

Write a program to implement the Producer –Consumer problem using semaphores using
UNIX/LINUX system calls.

OBJECTIVE

To implement the Producer –Consumer problem using semaphores using UNIX / LINUX
system calls.

DESCRIPTION
Producerconsumerproblemisalsoknownasboundedbufferproblem.Inthisproblemwehavetwo
processes, producer and consumer, who share a fixed size buffer. Producer work is to produce
data or items and put in buffer. Consumer work is to remove data from buffer and consume it.
We have
tomakesurethatproducerdonotproducedatawhenbufferisfullandconsumerdonotremovedata when
buffer is empty.

The producer should go to sleep when buffer is full. Next time when consumer removes data it
notifies the producer and producer starts producing data again. The consumer should go to
sleep when buffer is empty. Next time when producer add data it notifies the consumer and
consumer starts consuming data. This solution can be achieved using semaphores.

PROGRAM

#include<stdio.h>
#include<stdlib.h>
int mutex = 1, full = 0, empty = 3, x = 0;
int wait(int);
int signal(int);
void producer();
void consumer();

int main()
{
int n;
printf("\n1. Producer\n2. Consumer\n3. Exit");
while(1) {

printf("\nEnter your choice: ");

scanf("%d", &n);

switch(n) {

case 1:

if(mutex == 1 && empty != 0)

producer();

else

printf("Buffer is full!!");

break;

case 2:

if(mutex == 1 && full != 0)

consumer();

else

printf("Buffer is empty!!");

break;

case 3:

exit(0);

break;

return 0;

int wait(int s) {
return (--s);

int signal(int s) {

return (++s);

void producer() {

mutex = wait(mutex);

full = signal(full);

empty = wait(empty);

x++;

printf("\nProducer produces the item %d", x);

mutex = signal(mutex);

void consumer() {

mutex = wait(mutex);

full = wait(full);

empty = signal(empty);

printf("\nConsumer consumes item %d", x);

x--;

mutex = signal(mutex);

}
Output
1. Producer
2. Consumer
3. Exit
Enter your choice:1

Producerproducestheitem1
Enter your choice:2

Consumerconsumesitem
1 Enter your choice:2
Buffer is empty!!
Enteryourchoice:
1

Producerproducestheitem1
Enter your choice:1

Producerproducestheitem2
Enter your choice:1

Producerproducestheitem3
Enter your choice:1
Buffer is full!!
Enteryourchoic
e:3
Experiment -4
Write a C program to simulate the concept of Dining-philosophers problem.

Algorithm

1. Initialize Constants and Resources:


 Set the number of philosophers (NUM_PHILOSOPHERS) and forks (forks) to
manage the resources.
 Create a list of philosophers (philosophers) to store the philosopher threads.
2. Define the Philosopher Class:
 Create a Philosopher class that inherits from threading.Thread.
 In the __init__ method, accept the philosopher's index and initialize it.
 Define run method to simulate the philosopher's actions.
3. Implement the think Method:
 Inside the Philosopher class, create a think method.
 Print a message indicating that the philosopher is thinking.
 Introduce a delay using time.sleep() to simulate thinking.
4. Implement the eat Method:
 Create an eat method in the Philosopher class.
 Acquire the forks using forks list and philosopher's index.
 Print a message indicating that the philosopher is eating.
 Introduce a delay to simulate eating time.
 Release the acquired forks.
5. Create Philosopher Threads:
 Use a loop to create instances of the Philosopher class for each philosopher
index.
 Append each philosopher to the philosophers list.
6. Start Philosopher Threads:
 Iterate through the philosophers list and start each philosopher thread using
the start() method.
7. Wait for Threads to Finish:
 Iterate through the philosophers list and call the join() method for each
philosopher thread.
 This ensures that the main program waits for all philosopher threads to finish
before proceeding.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define NUM_PHILOSOPHERS 5
#define NUM_EATING_CYCLES 3

pthread_mutex_t forks[NUM_PHILOSOPHERS];
pthread_t philosophers[NUM_PHILOSOPHERS];

void *philosopher_action(void *philosopher_id) {


int id = *(int *)philosopher_id;
int left_fork = id;
int right_fork = (id + 1) % NUM_PHILOSOPHERS;

for (int cycle = 0; cycle < NUM_EATING_CYCLES; cycle++) {


// Thinking
printf("Philosopher %d is thinking...\n", id);
usleep(rand() % 1000000);

// Pick up forks
pthread_mutex_lock(&forks[left_fork]);
pthread_mutex_lock(&forks[right_fork]);

// Eating
printf("Philosopher %d is eating...\n", id);
usleep(rand() % 1000000);

// Put down forks


pthread_mutex_unlock(&forks[right_fork]);
pthread_mutex_unlock(&forks[left_fork]);
}

printf("Philosopher %d has finished eating.\n", id);


pthread_exit(NULL);
}
int main() {
srand(time(NULL));

for (int i = 0; i < NUM_PHILOSOPHERS; i++) {


pthread_mutex_init(&forks[i], NULL);
}

for (int i = 0; i < NUM_PHILOSOPHERS; i++) {


int *id = malloc(sizeof(int));
*id = i;
pthread_create(&philosophers[i], NULL, philosopher_action, id);
}

for (int i = 0; i < NUM_PHILOSOPHERS; i++) {


pthread_join(philosophers[i], NULL);
pthread_mutex_destroy(&forks[i]);
}

return 0;
}
EXPERIMENT-5

Write a C program to simulate the following techniques of memory management


a) Paging b) Segmentation

OBJECTIVE

Write a C program to simulate paging technique of memory management.

DESCRIPTION

In computer operating systems, paging is one of the memory management schemes by which a
computer stores and retrieves data from the secondary storage for use in main memory. In the
paging memory-management scheme the operating system retrieves data from secondary storage in
same-size blocks called pages. Paging is a memory-management scheme that permits the physical
address space a process to be noncontiguous. The basic method for implementing paging involves
breaking physical memory into fixed-sized blocks called frames and breaking logical memory into
blocks of the same size called pages. When a process Is to be executed, its pages are loaded into
any available memory frames from their source.

AIM: To simulate paging technique of memory management.

PROGRAM

#include <stdio.h>

#include <conio.h>

int main() {

int ms, ps, nop, np, rempages, i, j, x, y, pa, offset;

int s[10], fno[10][20];

clrscr();
printf("\nEnter the memory size: ");

scanf("%d", &ms);

printf("Enter the page size: ");

scanf("%d", &ps);

nop = ms / ps;

printf("The number of pages available in memory are: %d\n", nop);

printf("Enter the number of processes: ");

scanf("%d", &np);

rempages = nop;

for (i = 1; i <= np; i++) {

printf("\nEnter the number of pages required for P[%d]: ", i);

scanf("%d", &s[i]);

if (s[i] > rempages) {

printf("\nMemory is Full\n");

break;

rempages = rempages - s[i];

printf("Enter page table for P[%d]: ", i);

for (j = 0; j < s[i]; j++)

scanf("%d", &fno[i][j]);

}
printf("\nEnter Logical Address to find Physical Address:\n");

printf("Enter process no., page number, and offset: ");

scanf("%d %d %d", &x, &y, &offset);

if (x > np || y >= s[i] || offset >= ps)

printf("\nInvalid Processor, Page Number, or Offset\n");

else {

pa = fno[x][y] * ps + offset;

printf("\nThe Physical Address is: %d\n", pa);

getch();

return 0;

INPUT
Enterthememorysize–1000 Enter
the page size --100
The no. of pages available in memory are --10
Enter number of processes --3
Enter no. of pages required for p[1]-- 4
Enter page table for p[1]--- 8 6 9 5
Enter no.of pages required forp[ 2]-- 5
Enter page table for p[2]--- 1 4 5 7 3
Enter no.of pages required for p[3]-- 5
OUTPUT
Memory is Full
Enter Logical Address to find Physical Address
Enter process no. and page number and offset--2 3 60
The Physical Address is------- 760
OBJECTIVE: To simulate segmentation technique of memory management.-

PROGRAM LOGIC:
a) Start the program.
b) Get the number of segments.
c) Get the base address and length for each segment.
d) Get the logical address.
e) Check whether the segment number is within the limit; if not, display the error
message.
f) Check whether the byte reference is within the limit; if not, display the error message.
g) Calculate the physical memory and display it.
h) Stop the program.

SOURCE CODE:

#include <stdio.h>
#include <conio.h>
#include <math.h>

int sost;
void gstinfo();
void ptladdr();

struct segtab {
int sno;
int baddr;
int limit;
int val[10];
} st[10];

void gstinfo() {
int i, j, swd, n, d = 0, s, disp, paddr;

printf("\n\tEnter the size of the segment table: ");


scanf("%d", &sost);

for (i = 1; i <= sost; i++) {


printf("\n\tEnter the information about segment: %d", i);
st[i].sno = i;
printf("\n\tEnter the base Address: ");
scanf("%d", &st[i].baddr);
printf("\n\tEnter the Limit: ");
scanf("%d", &st[i].limit);

for (j = 0; j <= sost; i++)


printf("\t\t%d\t\t%d\t\t%d\n\n", st[i].sno, st[i].baddr, st[i].limit);
}

printf("\n\nEnter the logical Address: ");


scanf("%d", &swd);
n = swd;
while (n != 0) {
n = n / 10;
d++;
}

s = swd / pow(10, d - 1);


disp = swd % (int)pow(10, d - 1);

if (s <= sost) {
if (disp < st[s].limit) {
paddr = st[s].baddr + disp;
printf("\n\t\tLogical Address is: %d", swd);
printf("\n\t\tMapped Physical address is: %d", paddr);
printf("\n\tThe value is: %d", (st[s].val[disp]));
} else {
printf("\n\t\tLimit of segment %d is high\n\n", s);
}
} else {
printf("\n\t\tInvalid Segment Address\n");
}
}

void main() {
char ch;

clrscr();
gstinfo();

do {
ptladdr();
printf("\n\tDo you want to Continue (Y/N)? ");
fflush(stdin);
scanf(" %c", &ch);
} while (ch == 'Y' || ch == 'y');
getch();
}

INPUTANDOUTPUT:
Enter the size of the segment table: 3
Enter the information about segment: 1
Enter the base Address: 4
Enter the Limit: 5
Enterthe4 address Value: 11
Enterthe5 address Value: 12
Enterthe6 address Value: 13
Enterthe7 address Value: 14
Enterthe8 address Value: 15
Entertheinformationaboutsegment:2
Enter the base Address: 5
Enter the Limit: 4
Enterthe5 address Value: 21
Enterthe6 address Value: 31
Enterthe7 address Value: 41

Enterthe8 address Value: 51


Entertheinformationaboutsegment:3
Enter the base Address: 3
Enter the Limit: 4
Enterthe3 address Value: 31
Enterthe4addressValue: 41
Enterthe5 address Value: 41
Enterthe6 address Value: 51
SEGMENTTABLESEG.NOBASEADDRESSLIMIT
145
254
334
EnterthelogicalAddress:3
Logical Address is: 3
MappedPhysicaladdressis:3 The
value is: 31
Do U want to Continue (Y/N)
SEGMENTTABLESEG.NOBASEADDRESSLIMIT
145
254
334
EnterthelogicalAddress:1
Logical Address is: 1
Mapped Physical address is:4
Thevalueis11DoUwanttoContinue(Y/N)
VIVA QUESTIONS:

1. The page table contains


2. What is compaction?
3. Operating System maintains the page table for
4. Physical memory is broken into fixed-sized blocks called
5. Logical memory is broken into blocks of the same size called
6. Every address generated by the CPU is divided into two parts:
7. The page number is used as an index into the page table.
8. The page table contains the base address of each page in physical
memory.
9. The size of a page is typically fixed.
10.With paging, there is no external fragmentation.
11.The operating system maintains a page table that keeps track of how
many frames have been allocated, how many are there, and how many are
available.
12.Paging increases the access time.
13.Smaller page tables are implemented as a set of page table registers.
14.The page table registers should be built with fast-access hardware.
15.For larger page tables, they are kept in main memory and a page table
base register points to the page table.
16.For every process, there is a separate page table.
17.Static address binding is done at compile time.
18.Dynamic address binding is done at runtime.
19.Address binding is done in three phases.
20.Segmentation defines logical addressing.
EXPERIMENT-6
Write a C program to illustrate the following IPC mechanisms
a) Pipes b) FIFOs c) Message Queues d)Shared Memory

OBJECTIVE:

Write a C program to illustrate the IPC mechanisms Pipes

PROGRAM

#include
<stdio.h>
#include
<unistd.h>
#defineMS
GSIZE16
char*msg1="hell
o,world#1";
char*msg2="hell
o,world#2";
char*msg3="hell
o,world#3";

int main()
{
charinbuf
[MSGSIZ
E]; int
p[2], i;

if(pipe(p)<0)
exit(1);

/*continued*/
/*writepipe*/

write(p[1],msg1
,MSGSIZE);
write(p[1],msg2
,MSGSIZE);
write(p[1],msg3
,MSGSIZE);

for(i= 0;i< 3;i++){


/*readpipe*/
read(p[0],inbuf,MS
GSIZE); printf("%
s\n", inbuf);
}
return0;
}
Output:

hello,world#1
hello,world#2
hello,world#3
OBJECTIVE
b) Write a C program to illustrate the FIFO IPC mechanism

PROGRAM

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include<sys/types.h>
#include <unistd.h>

int main()
{
intfd;

//FIFO filepath
char*myfifo="/tmp/myfifo";

//Creatingthenamedfile(FIFO)
//mkfifo(<pathname>,<permission>)
mkfifo(myfifo, 0666);

chararr1[80],arr2[80];
while (1)
{
//OpenFIFOforwriteonly
fd=open(myfifo,O_WRONLY);

//Takeaninputarr2ingfromuser.
//80ismaximumlength fgets(arr2,
80, stdin);

//Writetheinputarr2ingonFIFO
//andcloseit
write(fd,arr2,strlen(arr2)+1); close(fd);

//OpenFIFOfor Readonly
fd=open(myfifo,O_RDONLY);

// Read from
FIFOread(fd,arr1,sizeof(ar
r1));

// Print the read message


printf("User2:%s\n",arr1);
close(fd);
}
return0;
}

Output:
OBJECTIVE
c) Write a C program to illustrate the Message Queue IPC mechanism

PROGRAM:

//C Program for Message Queue (Writer Process)


#include <stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>

//structureformessagequeue
struct mesg_buffer {
long
mesg_type;charmesg
_text[100];
} message;

int main()
{
key_tkey;
intmsgid;

//ftoktogenerateuniquekey
key = ftok("progfile", 65);

//msggetcreatesamessage queue
//andreturnsidentifier
msgid=msgget(key,0666|IPC_CREAT);
message.mesg_type = 1;

printf("Write Data : ");


gets(message.mesg_text);

//msgsndtosendmessage
msgsnd(msgid,&message,sizeof(message),0);

//displaythemessage
printf("Datasend is:%s\n",message.mesg_text);

return0;
}

////C Program for Message Queue (ReaderProcess)


#include <stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>

//structureformessagequeue
struct mesg_buffer {
long
mesg_type;charmesg
_text[100];
} message;

int main()
{
key_tkey;
intmsgid;

//ftoktogenerateuniquekey
key = ftok("progfile", 65);

//msggetcreatesamessage queue
//andreturnsidentifier
msgid=msgget(key,0666|IPC_CREAT);

//msgrcvtoreceivemessage
msgrcv(msgid,&message,sizeof(message),1,0);

// display the message


printf("DataReceivedis:%s\n",
message.mesg_text);

// to destroy the message queue


msgctl(msgid,IPC_RMID,NULL);

return0;
}
Output:
OBJECTIVE
d) Write a C program to illustrate the Shared Memory IPC mechanism

PROGRAM:

#include <iostream>
#include <sys/ipc.h>
#include<sys/shm.h>
#include <stdio.h>
using namespace std;

int main()
{
// ftok to generate unique key
key_tkey=ftok("shmfile",65);

//shmgetreturnsanidentifierinshmid
intshmid=shmget(key,1024,0666|IPC_CREAT);

//shmattoattachtosharedmemory
char *str=(char*)shmat(shmid,(void*)0,0);

cout<<"WriteData:";
gets(str);

printf("Datawritteninmemory:%s\n",str);

//detachfromsharedmemory
shmdt(str);

return0;
}
SHARED MEMORY FOR READER PROCESS

#include <iostream>
#include <sys/ipc.h>
#include<sys/shm.h>
#include <stdio.h>
using namespace std;

int main()
{
// ftok to generate unique key
key_tkey=ftok("shmfile",65);

//shmgetreturnsanidentifierinshmid
intshmid=shmget(key,1024,0666|IPC_CREAT);

//shmattoattachtosharedmemory
char*str=(char*)shmat(shmid,(void*)0,0);

printf("Data read from memory: %s\n",str);

//detachfromsharedmemory
shmdt(str);

// destroy the shared memory


shmctl(shmid,IPC_RMID,NULL);

return0;
}

Output:
VIVA QUESTIONS

1. What are local and global page replacements?


2. Define latency, transfer and seek time with respect to disk I/O.
3. Describe the Buddy system of memory allocation.
4. What is time-stamping?
5. How are the wait/signal operations for monitor different from those for
semaphores?
6. In the context of memory management, what are replacement and
replacement algorithms?
7. In loading programs into memory, what is the difference between load-time
dynamic linking and run-time dynamic linking?
8. What are demand-paging and pre-paging?
9. Paging, a memory management function, while multiprogramming, a
processor management function, are the two interdependent?
10. What is page cannibalizing?
11. What has triggered the need for multitasking in PCs?
12. What are the four layers that Windows NT have in order to achieve
independence?
13. Explain compaction.
14. What are page frames?
15. What are pages?
16. Differentiate between logical and physical address.
17. When does page fault error occur?
18. Explain thrashing.
19. What is the criteria for the best page replacement algorithm?
20. What is Belady’s anomaly?
Experiment 7a.

Write a C Program to simulate worst fit contiguous memory allocation Techniques

Algorithm

1. Define Structures and Constants:


 Define a structure named MemoryBlock with fields to represent memory blocks: id,
size, and allocated.
2. Input Memory Block Information:
 Prompt the user to enter the number of memory blocks (numBlocks).
 Initialize an array of MemoryBlock structures named blocks.
3. Initialize Memory Blocks:
 Use a loop to initialize each memory block by assigning an ID and prompting the
user for the size of each block.
 Set the allocated field to 0 to indicate that the block is not allocated.
4. Input Process Information:
 Prompt the user to enter the number of processes (numProcesses).
5. Allocate Memory to Processes (Worst Fit):
 For each process, prompt the user to enter the size of the process (processSize).
 Iterate through the blocks array to find the largest available memory block that
can accommodate the process.
 If a suitable block is found, mark it as allocated, and print the allocation details.
 If no suitable block is found, print a message indicating that memory allocation
failed for the process.
6. Main Function:
 Inside the main function, call the steps above in sequence.

#include <stdio.h>

#define MAX_BLOCKS 10

// Structure to represent a memory block


struct MemoryBlock {
int id;
int size;
int allocated;
};
// Function to allocate memory using worst fit technique
void allocateMemory(struct MemoryBlock blocks[], int numBlocks, int processSize) {
int largestBlockIndex = -1;

// Find the largest available block that can accommodate the process
for (int i = 0; i < numBlocks; i++) {
if (!blocks[i].allocated && blocks[i].size >= processSize) {
if (largestBlockIndex == -1 || blocks[i].size > blocks[largestBlockIndex].size) {
largestBlockIndex = i;
}
}
}

if (largestBlockIndex != -1) {
// Allocate memory to the process
blocks[largestBlockIndex].allocated = 1;
printf("Allocated Memory Block %d to Process of Size %d\n",
blocks[largestBlockIndex].id, processSize);
} else {
printf("Unable to Allocate Memory for Process of Size %d\n", processSize);
}
}

int main() {
struct MemoryBlock blocks[MAX_BLOCKS];
int numBlocks;

printf("Enter the number of memory blocks: ");


scanf("%d", &numBlocks);

// Initialize memory blocks


for (int i = 0; i < numBlocks; i++) {
blocks[i].id = i + 1;
printf("Enter size of Memory Block %d: ", blocks[i].id);
scanf("%d", &blocks[i].size);
blocks[i].allocated = 0;
}

int numProcesses;
printf("Enter the number of processes: ");
scanf("%d", &numProcesses);

// Allocate memory to processes


for (int i = 0; i < numProcesses; i++) {
int processSize;
printf("Enter size of Process %d: ", i + 1);
scanf("%d", &processSize);
allocateMemory(blocks, numBlocks, processSize);
}

return 0;
}
Experiment 7b.

Write a C Program to simulate best fit contiguous memory allocation Techniques

Algorithm

1. Define Structures and Constants:


 Define a structure named MemoryBlock with fields to represent memory blocks: id,
size, allocated, and optionally, a field to track the remaining size after allocation.
2. Input Memory Block Information:
 Prompt the user to enter the number of memory blocks (numBlocks).
 Initialize an array of MemoryBlock structures named blocks.
3. Initialize Memory Blocks:
 Use a loop to initialize each memory block by assigning an ID and prompting the
user for the size of each block.
 Set the allocated field to 0 to indicate that the block is not allocated.
4. Input Process Information:
 Prompt the user to enter the number of processes (numProcesses).
5. Allocate Memory to Processes (Best Fit):
 For each process, prompt the user to enter the size of the process (processSize).
 Iterate through the blocks array to find the smallest available memory block that
can accommodate the process.
 If a suitable block is found, mark it as allocated, update its remaining size, and
print the allocation details.
 If no suitable block is found, print a message indicating that memory allocation
failed for the process.
6. Main Function:
 Inside the main function, call the steps above in sequence.

#include <stdio.h>

#define MAX_BLOCKS 10

// Structure to represent a memory block


struct MemoryBlock {
int id;
int size;
int allocated;
};

// Function to allocate memory using best fit technique


void allocateMemory(struct MemoryBlock blocks[], int numBlocks, int processSize) {
int bestFitIndex = -1;
int smallestSize = -1;

// Find the smallest available block that can accommodate the process
for (int i = 0; i < numBlocks; i++) {
if (!blocks[i].allocated && blocks[i].size >= processSize) {
if (bestFitIndex == -1 || blocks[i].size < smallestSize) {
bestFitIndex = i;
smallestSize = blocks[i].size;
}
}
}

if (bestFitIndex != -1) {
// Allocate memory to the process
blocks[bestFitIndex].allocated = 1;
blocks[bestFitIndex].size -= processSize;
printf("Allocated Memory Block %d to Process of Size %d\n",
blocks[bestFitIndex].id, processSize);
} else {
printf("Unable to Allocate Memory for Process of Size %d\n", processSize);
}
}

int main() {
struct MemoryBlock blocks[MAX_BLOCKS];
int numBlocks;

printf("Enter the number of memory blocks: ");


scanf("%d", &numBlocks);

// Initialize memory blocks


for (int i = 0; i < numBlocks; i++) {
blocks[i].id = i + 1;
printf("Enter size of Memory Block %d
Experiment 7c.

Write a C Program to simulate First fit contiguous memory allocation Techniques

Algorithm

1. Define Structures and Constants:


 Define a structure named MemoryBlock with fields to represent memory blocks: id,
size, and allocated.
2. Input Memory Block Information:
 Prompt the user to enter the number of memory blocks (numBlocks).
 Initialize an array of MemoryBlock structures named blocks.
3. Initialize Memory Blocks:
 Use a loop to initialize each memory block by assigning an ID and prompting the
user for the size of each block.
 Set the allocated field to 0 to indicate that the block is not allocated.
4. Input Process Information:
 Prompt the user to enter the number of processes (numProcesses).
5. Allocate Memory to Processes (First Fit):
 For each process, prompt the user to enter the size of the process (processSize).
 Iterate through the blocks array to find the first available memory block that can
accommodate the process.
 If a suitable block is found, mark it as allocated, update its remaining size, and
print the allocation details.
 If no suitable block is found, print a message indicating that memory allocation
failed for the process.
6. Main Function:
 Inside the main function, call the steps above in sequence.

Here's the summarized step-by-step procedure:

1. Define structures and constants.


2. Input the number of memory blocks (numBlocks).
3. Initialize an array of MemoryBlock structures and input memory block sizes.
4. Input the number of processes (numProcesses).
5. For each process:
 Input the size of the process (processSize).
 Find the first available memory block that can accommodate the process (first fit).
 If found, mark the block as allocated, update its remaining size, and print
allocation details.
6. End the program
// first fit
#include <stdio.h>

#define MAX_BLOCKS 10

// Structure to represent a memory block


struct MemoryBlock {
int id;
int size;
int allocated;
};

// Function to allocate memory using first fit technique


void allocateMemory(struct MemoryBlock blocks[], int numBlocks, int processSize) {
int firstFitIndex = -1;

// Find the first available block that can accommodate the process
for (int i = 0; i < numBlocks; i++) {
if (!blocks[i].allocated && blocks[i].size >= processSize) {
firstFitIndex = i;
break;
}
}

if (firstFitIndex != -1) {
// Allocate memory to the process
blocks[firstFitIndex].allocated = 1;
blocks[firstFitIndex].size -= processSize;
printf("Allocated Memory Block %d to Process of Size %d\n",
blocks[firstFitIndex].id, processSize);
} else {
printf("Unable to Allocate Memory for Process of Size %d\n", processSize);
}
}

int main() {
struct MemoryBlock blocks[MAX_BLOCKS];
int numBlocks;

printf("Enter the number of memory blocks: ");


scanf("%d", &numBlocks);

// Initialize memory blocks


for (int i = 0; i < numBlocks; i++) {
blocks[i].id = i + 1;
printf("Enter size of Memory Block %d: ", blocks[i].id);
scanf("%d", &blocks[i].size);
blocks[i].allocated = 0;
}

int numProcesses;
printf("Enter the number of processes: ");
scanf("%d", &numProcesses);

// Allocate memory to processes


for (int i = 0; i < numProcesses; i++) {
int processSize;
printf("Enter size of Process %d: ", i + 1);
scanf("%d", &processSize);
allocateMemory(blocks, numBlocks, processSize);
}

return 0;
}
Experiment 8a.

Write a File Organization Technique C program to simulate Single level directory

Algorithm

1. Define Structures and Constants:


 Define a structure named File with fields to represent a file: filename and size.
 Define a structure named Directory with an array of File structures and an int
to track the number of files (fileCount).
 Define constants such as MAX_FILES and MAX_FILENAME_LENGTH for the maximum
number of files and filename length.
2. Create File Function:
 Define a function named createFile that accepts pointers to a Directory, a
filename, and a size.
 Check if the directory is full. If so, print a message indicating that no more files can
be created.
 Check if a file with the same name already exists. If so, print an error message.
 Otherwise, add the file information to the Directory's files array and increment
the fileCount.
3. Delete File Function:
 Define a function named deleteFile that accepts pointers to a Directory and a
filename to be deleted.
 Search for the file in the files array by comparing filenames.
 If the file is found, shift files to close the gap and decrement the fileCount.
 If the file is not found, print an error message.
4. List Files Function:
 Define a function named listFiles that accepts a pointer to a Directory.
 Check if there are no files in the directory. If so, print a message indicating there
are no files.
 Otherwise, iterate through the files array and print the filenames and sizes.
5. Main Function:
 Inside the main function, create a Directory structure.
 Use a loop to display a menu to the user with options for creating, deleting, listing
files, and exiting.
 Depending on the user's choice, call the corresponding functions.

Here's the summarized step-by-step procedure:

1. Define structures and constants.


2. Define a function to create a file.
3. Define a function to delete a file.
4. Define a function to list files.
5. Inside the main function:
 Create a Directory structure.
 Display a menu to the user.
 Based on the user's choice, call the appropriate functions.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_FILES 100


#define MAX_FILENAME_LENGTH 50

struct File {
char filename[MAX_FILENAME_LENGTH];
int size;
};

struct Directory {
struct File files[MAX_FILES];
int fileCount;
};

void createFile(struct Directory *directory, char *filename, int size) {


if (directory->fileCount >= MAX_FILES) {
printf("Directory is full. Cannot create more files.\n");
return;
}

for (int i = 0; i < directory->fileCount; i++) {


if (strcmp(directory->files[i].filename, filename) == 0) {
printf("File with the same name already exists.\n");
return;
}
}

strcpy(directory->files[directory->fileCount].filename, filename);
directory->files[directory->fileCount].size = size;
directory->fileCount++;

printf("File '%s' created successfully.\n", filename);


}

void deleteFile(struct Directory *directory, char *filename) {


for (int i = 0; i < directory->fileCount; i++) {
if (strcmp(directory->files[i].filename, filename) == 0) {
// Shift files to fill the gap
for (int j = i; j < directory->fileCount - 1; j++) {
directory->files[j] = directory->files[j + 1];
}
directory->fileCount--;

printf("File '%s' deleted successfully.\n", filename);


return;
}
}

printf("File '%s' not found.\n", filename);


}

void listFiles(struct Directory *directory) {


if (directory->fileCount == 0) {
printf("No files in the directory.\n");
return;
}

printf("List of files:\n");
for (int i = 0; i < directory->fileCount; i++) {
printf("File: %s, Size: %d bytes\n", directory->files[i].filename, directory-
>files[i].size);
}
}

int main() {
struct Directory directory;
directory.fileCount = 0;
while (1) {
printf("\nMenu:\n");
printf("1. Create File\n");
printf("2. Delete File\n");
printf("3. List Files\n");
printf("4. Exit\n");
printf("Enter your choice: ");

int choice;
scanf("%d", &choice);

switch (choice) {
case 1:
char filename[MAX_FILENAME_LENGTH];
int size;
printf("Enter filename: ");
scanf("%s", filename);
printf("Enter file size: ");
scanf("%d", &size);
createFile(&directory, filename, size);
break;

case 2:
printf("Enter filename to delete: ");
scanf("%s", filename);
deleteFile(&directory, filename);
break;

case 3:
listFiles(&directory);
break;

case 4:
printf("Exiting program.\n");
exit(0);

default:
printf("Invalid choice. Please enter a valid option.\n");
break;
}
}

return 0;
}

Experiment 8b.

Write a File Organization Technique C program to simulate Two level directory

Algorithm

Step 1: Initialize the Root Directory

1. Create a structure to represent a file. Each file structure should contain a name field.
2. Create a structure to represent a directory. Each directory structure should contain a
name field, an array of file structures (representing files contained in the directory), and a
counter to keep track of the number of files in the directory.
3. Initialize the root directory structure. Set its name to "root" and the number of files to 0.

Step 2: Creating Files

1. Display a menu to the user with options to perform various actions.


2. If the user selects the option to create a file:
 Prompt the user to enter the name of the file.
 Check if the number of files in the current directory is less than the maximum
allowed.
 If yes, add the new file's name to the array of files in the current directory
and increment the file counter.
 If no, display an error message indicating that the directory is full.

Step 3: Displaying Directory Contents

1. If the user selects the option to display directory contents:


 Iterate through the array of files in the current directory.
 Display the names of all files in the directory.

Step 4: Creating Subdirectories

1. If the user selects the option to create a subdirectory:


 Prompt the user to enter the name of the subdirectory.
 Check if the number of subdirectories is less than the maximum allowed.
 If yes, create a new directory structure with the provided name and initialize
its file counter to 0.
 If no, display an error message indicating that the maximum number of
subdirectories has been reached.

Step 5: Exiting the Program

1. If the user selects the option to exit the program:


 Display a farewell message.
 Terminate the program.

Step 6: Repeat

1. After each operation, return to the main menu and allow the user to perform more
actions until they choose to exit.

Step 7: Compile and Run

1. Compile the program using a C compiler.


2. Run the compiled executable.
3. Interact with the program by choosing options from the menu to create files, display
directory contents, create subdirectories, and exit the program

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_DIRS 100


#define MAX_FILES 100
#define MAX_NAME_LENGTH 50

typedef struct {
char name[MAX_NAME_LENGTH];
} File;

typedef struct {
char name[MAX_NAME_LENGTH];
File files[MAX_FILES];
int num_files;
} Directory;

Directory root_directory;
Directory subdirectories[MAX_DIRS];
int num_subdirectories = 0;

void createFile(Directory *dir, char *name) {


if (dir->num_files < MAX_FILES) {
strcpy(dir->files[dir->num_files].name, name);
dir->num_files++;
printf("File '%s' created in directory '%s'.\n", name, dir->name);
} else {
printf("Directory '%s' is full.\n", dir->name);
}
}

void displayDirectory(Directory *dir) {


printf("Contents of directory '%s':\n", dir->name);
for (int i = 0; i < dir->num_files; i++) {
printf("- %s\n", dir->files[i].name);
}
}

void createSubdirectory(char *name) {


if (num_subdirectories < MAX_DIRS) {
strcpy(subdirectories[num_subdirectories].name, name);
subdirectories[num_subdirectories].num_files = 0;
num_subdirectories++;
printf("Subdirectory '%s' created.\n", name);
} else {
printf("Maximum number of subdirectories reached.\n");
}
}

int main() {
strcpy(root_directory.name, "root");
root_directory.num_files = 0;

int choice;
char name[MAX_NAME_LENGTH];

do {
printf("\nTwo-Level Directory Simulation Menu:\n");
printf("1. Create file\n");
printf("2. Display directory contents\n");
printf("3. Create subdirectory\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);

switch (choice) {
case 1:
printf("Enter file name: ");
scanf("%s", name);
createFile(&root_directory, name);
break;
case 2:
displayDirectory(&root_directory);
break;
case 3:
printf("Enter subdirectory name: ");
scanf("%s", name);
createSubdirectory(name);
break;
case 4:
printf("Exiting program.\n");
break;
default:
printf("Invalid choice. Please enter a valid option.\n");
}
} while (choice != 4);

return 0;
}
Experiment 9a.
Write a C Program for FIFO Page Replacement Algorithm

FIFO Page Replacement Algorithm: Step-by-Step Procedure

Step 1: Initialize

1. Initialize an empty queue to represent the page frames in memory.


2. Initialize a variable to keep track of the current position in the queue (the position where
the next page will be placed).

Step 2: Page Request

1. When a page request is received:


 Check if the requested page is already in a page frame.
 If yes, it's a page hit. No need to make any changes. Continue to the next
page request.
 If no, it's a page fault (miss):
 Check if there is an empty page frame available.
 If yes, place the requested page in the empty page frame and
enqueue it in the queue. Update the current position in the queue.
 If no, a page replacement is required:
 Dequeue the page at the front of the queue (the oldest
page) to make space.
 Enqueue the requested page in the queue.
 Update the current position in the queue.

Step 3: Repeat

1. Continue processing page requests one by one, following the steps outlined in Step 2.
2. Keep track of the number of page faults that occur during this process.

Step 4: End

1. Once all page requests have been processed, calculate and report the total number of
page faults.

Note: The FIFO algorithm is relatively simple and straightforward to implement. However, it
suffers from the "Belady's Anomaly," where increasing the number of page frames can lead to
an increase in the number of page faults. This is because the oldest pages are replaced,
regardless of how frequently they are accessed.

Example: Let's consider a simple example with a page frame size of 3 and the following page
request sequence: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5.

Initial state: Queue is empty. Page request 1: Queue: [1], Page Fault. Page request 2: Queue: [1,
2], Page Fault. Page request 3: Queue: [1, 2, 3], Page Fault. Page request 4: Queue: [2, 3, 4], Page
Fault. Page request 1: Queue: [2, 3, 4], Page Hit. Page request 2: Queue: [2, 3, 4], Page Hit. Page
request 5: Queue: [3, 4, 5], Page Fault (Replace 2). ...and so on.

Total page faults: 7.

#include <stdio.h>
int main()
{
int referenceString[50], pageFaults = 0, m, n, s, pages, frames;
printf("\nEnter the number of Pages:\t");
scanf("%d", &pages);
printf("\nEnter reference string values:\n");
for( m = 0; m < pages; m++)
{
printf("Value No. [%d]:\t", m + 1);
scanf("%d", &referenceString[m]);
}
printf("\n What are the total number of frames:\t");
{
scanf("%d", &frames);
}
int temp[frames];
for(m = 0; m < frames; m++)
{
temp[m] = -1;
}
for(m = 0; m < pages; m++)
{
s = 0;
for(n = 0; n < frames; n++)
{
if(referenceString[m] == temp[n])
{
s++;
pageFaults--;
}
}
pageFaults++;
if((pageFaults<= frames) && (s == 0))
{
temp[m] = referenceString[m];
}
else if(s == 0)
{
temp[(pageFaults - 1) % frames] = referenceString[m];
}
printf("\n");
for(n = 0; n < frames; n++)
{
printf("%d\t", temp[n]);
}
}
printf("\nTotal Page Faults:\t%d\n", pageFaults);
return 0;
}

Experiment 9b.
Write a C Program for LRU Page Replacement Algorithm

LRU Page Replacement Algorithm: Step-by-Step Procedure

Step 1: Initialize

1. Initialize a data structure (such as a queue or linked list) to maintain the order of page
frames in memory.
Step 2: Page Request

1. When a page request is received:


 Check if the requested page is already in a page frame.
 If yes, it's a page hit. Update the position of the page in the data structure
to indicate that it was recently used. No need to make any changes. Continue to
the next page request.
 If no, it's a page fault (miss):
 Check if there is an empty page frame available.
 If yes, place the requested page in the empty page frame and
insert it into the data structure to represent its recent use.
 If no, a page replacement is required:
 Find the page that was least recently used in the data
structure (typically at the front of the queue or the beginning
of the linked list).
 Remove the least recently used page from the page
frame and the data structure.
 Place the requested page in the freed page frame and
insert it into the data structure to represent its recent use.

Step 3: Repeat

1. Continue processing page requests one by one, following the steps outlined in Step 2.
2. Keep track of the number of page faults that occur during this process.

Step 4: End

1. Once all page requests have been processed, calculate and report the total number of
page faults.

Note: The LRU algorithm aims to minimize page faults by replacing the page that has not been
used for the longest time. However, implementing the LRU algorithm can be challenging in
practice, as maintaining an accurate record of the order of page usage can be resource-
intensive. Various data structures and strategies can be used to implement the LRU algorithm
efficiently.

Example: Let's consider a simple example with a page frame size of 3 and the following page
request sequence: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5.

Initial state: Queue is empty. Page request 1: Queue: [1], Page Fault. Page request 2: Queue: [1,
2], Page Fault. Page request 3: Queue: [1, 2, 3], Page Fault. Page request 4: Queue: [2, 3, 4], Page
Fault. Page request 1: Queue: [3, 4, 1], Page Fault (Replace 2, as it's the least recently used). Page
request 2: Queue: [4, 1, 2], Page Fault (Replace 3). Page request 5: Queue: [1, 2, 5], Page Fault
(Replace 4). ...and so on.

Total page faults: 7.

#include<stdio.h>

int findLRU(int time[], int n){


int i, minimum = time[0], pos = 0;

for(i = 1; i< n; ++i){


if(time[i] <minimum){
minimum = time[i];
pos = i;
}
}
return pos;
}

int main()
{
int no_of_frames, no_of_pages, frames[10], pages[30], counter = 0,
time[10], flag1, flag2, i, j, pos, faults = 0;
printf("Enter number of frames: ");
scanf("%d" , &no_of_frames);
printf("Enter number of pages: ");
scanf("%d", &no_of_pages);
printf("Enter reference string: ");
for(i = 0; i<no_of_pages; ++i){
scanf("%d", &pages[i]);
}

for(i = 0; i<no_of_frames; ++i){


frames[i] = -1;
}
for(i = 0; i<no_of_pages; ++i){
flag1 = flag2 = 0;

for(j = 0; j <no_of_frames; ++j){


if(frames[j] == pages[i]){
counter++;
time[j] = counter;
flag1 = flag2 = 1;
break;
}
}

if(flag1 == 0){
for(j = 0; j <no_of_frames; ++j){
if(frames[j] == -1){
counter++;
faults++;
frames[j] = pages[i];
time[j] = counter;
flag2 = 1;
break;
}
}
}

if(flag2 == 0){
pos = findLRU(time, no_of_frames);
counter++;
faults++;
frames[pos] = pages[i];
time[pos] = counter;
}

printf("\n");
for(j = 0; j <no_of_frames; ++j){
printf("%d\t", frames[j]);
}
}
printf("\n\nTotal Page Faults = %d", faults);

return 0;
}

Experiment 9C.
Write a C Program for LFU Page Replacement Algorithm

LFU Page Replacement Algorithm: Step-by-Step Procedure

Step 1: Initialize Data Structures

1. Initialize a data structure to hold the page frames in memory. Each entry should include
the page number and a counter to track its frequency of access.
2. Initialize a variable to keep track of the total number of page frames.

Step 2: Page Request

1. When a page request is received:


 Check if the requested page is already in a page frame.
 If yes, it's a page hit. Increment the frequency counter of the corresponding
page frame. Continue to the next page request.
 If no, it's a page fault (miss):
 Check if there is an empty page frame available.
 If yes, place the requested page in the empty page frame and
set its frequency counter to 1.
 If no, a page replacement is required:
 Find the page frame with the lowest frequency count. If
there are ties, choose the one that arrived earliest.
 Replace the chosen page frame with the requested
page and set its frequency counter to 1.

Step 3: Repeat
1. Continue processing page requests one by one, following the steps outlined in Step 2.
2. Keep track of the number of page faults that occur during this process.

Step 4: End

1. Once all page requests have been processed, calculate and report the total number of
page faults.

Example: Let's consider a simple example with a page frame size of 3 and the following page
request sequence: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5.

Initial state: Page frames are empty. Page request 1: Page frames: [1 (1)], Page Fault. Page
request 2: Page frames: [1 (1), 2 (1)], Page Fault. Page request 3: Page frames: [1 (1), 2 (1), 3 (1)],
Page Fault. Page request 4: Page frames: [2 (1), 3 (1), 4 (1)], Page Fault. Page request 1: Page
frames: [2 (1), 3 (1), 4 (2)], Page Hit (Increment frequency). Page request 2: Page frames: [2 (1), 3
(1), 4 (3)], Page Hit (Increment frequency). Page request 5: Page frames: [3 (1), 4 (3), 5 (1)], Page
Fault (Replace 2 with the lowest frequency). ...and so on.

Total page faults: 6.

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_FRAMES 3
#define MAX_PAGES 20

typedef struct {
int page_number;
int frequency;
} Page;

Page frames[MAX_FRAMES];
int num_frames = 0;

int page_queue[MAX_PAGES];
int num_pages = 0;

void initializeFrames() {
for (int i = 0; i < MAX_FRAMES; i++) {
frames[i].page_number = -1;
frames[i].frequency = 0;
}
}

int findPage(int page_number) {


for (int i = 0; i < num_frames; i++) {
if (frames[i].page_number == page_number) {
return i;
}
}
return -1;
}

int findLFUPage() {
int min_frequency = INT_MAX;
int min_frequency_index = -1;

for (int i = 0; i < num_frames; i++) {


if (frames[i].frequency < min_frequency) {
min_frequency = frames[i].frequency;
min_frequency_index = i;
}
}
return min_frequency_index;
}

void displayFrames() {
printf("Current frames: ");
for (int i = 0; i < num_frames; i++) {
if (frames[i].page_number != -1) {
printf("%d (%d) ", frames[i].page_number, frames[i].frequency);
}
}
printf("\n");
}

void replacePage(int page_number) {


int replace_index = findLFUPage();
frames[replace_index].page_number = page_number;
frames[replace_index].frequency = 1;
}

int main() {
initializeFrames();

int page_number;
printf("Enter the number of pages: ");
scanf("%d", &num_pages);

printf("Enter the page reference sequence:\n");


for (int i = 0; i < num_pages; i++) {
scanf("%d", &page_queue[i]);
}

for (int i = 0; i < num_pages; i++) {


page_number = page_queue[i];
int frame_index = findPage(page_number);

if (frame_index != -1) {
frames[frame_index].frequency++;
} else {
if (num_frames < MAX_FRAMES) {
frames[num_frames].page_number = page_number;
frames[num_frames].frequency = 1;
num_frames++;
} else {
replacePage(page_number);
}
}

printf("Page reference: %d\n", page_number);


displayFrames();
}

return 0;
}

You might also like