OS LAB Manual Periasamy S
OS LAB Manual Periasamy S
OS LAB Manual Periasamy S
Operating Systems
LAB MANUAL
Prepared by
Periasamy S
Associate Professor
DEPARTMENT OF COMPUTERSCIENCE AND ENGINEERING
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
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
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.
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
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.
THEORY:
Example of Non Pre-emptive SJF
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
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;
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;
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:
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;
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;
}
awt = (float)swt / n;
atat = (float)stat / n;
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;
s = bt[i];
bt[i] = bt[j];
bt[j] = s;
s = pno[i];
pno[i] = pno[j];
pno[j] = s;
}
}
}
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:
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.
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:
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
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\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
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:
OBJECTIVE
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:
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>
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]);
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:
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) {
scanf("%d", &n);
switch(n) {
case 1:
producer();
else
printf("Buffer is full!!");
break;
case 2:
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++;
mutex = signal(mutex);
void consumer() {
mutex = wait(mutex);
full = wait(full);
empty = signal(empty);
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
#define NUM_PHILOSOPHERS 5
#define NUM_EATING_CYCLES 3
pthread_mutex_t forks[NUM_PHILOSOPHERS];
pthread_t philosophers[NUM_PHILOSOPHERS];
// 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);
return 0;
}
EXPERIMENT-5
OBJECTIVE
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.
PROGRAM
#include <stdio.h>
#include <conio.h>
int main() {
clrscr();
printf("\nEnter the memory size: ");
scanf("%d", &ms);
scanf("%d", &ps);
nop = ms / ps;
scanf("%d", &np);
rempages = nop;
scanf("%d", &s[i]);
printf("\nMemory is Full\n");
break;
scanf("%d", &fno[i][j]);
}
printf("\nEnter Logical Address to find Physical Address:\n");
else {
pa = fno[x][y] * ps + offset;
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;
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
OBJECTIVE:
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);
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));
Output:
OBJECTIVE
c) Write a C program to illustrate the Message Queue IPC mechanism
PROGRAM:
//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;
//msgsndtosendmessage
msgsnd(msgid,&message,sizeof(message),0);
//displaythemessage
printf("Datasend is:%s\n",message.mesg_text);
return0;
}
//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);
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);
//detachfromsharedmemory
shmdt(str);
return0;
}
Output:
VIVA QUESTIONS
Algorithm
#include <stdio.h>
#define MAX_BLOCKS 10
// 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;
int numProcesses;
printf("Enter the number of processes: ");
scanf("%d", &numProcesses);
return 0;
}
Experiment 7b.
Algorithm
#include <stdio.h>
#define MAX_BLOCKS 10
// 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;
Algorithm
#define MAX_BLOCKS 10
// 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;
int numProcesses;
printf("Enter the number of processes: ");
scanf("%d", &numProcesses);
return 0;
}
Experiment 8a.
Algorithm
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct File {
char filename[MAX_FILENAME_LENGTH];
int size;
};
struct Directory {
struct File files[MAX_FILES];
int fileCount;
};
strcpy(directory->files[directory->fileCount].filename, filename);
directory->files[directory->fileCount].size = size;
directory->fileCount++;
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.
Algorithm
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 6: Repeat
1. After each operation, return to the main menu and allow the user to perform more
actions until they choose to exit.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
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
Step 1: Initialize
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.
#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
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
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.
#include<stdio.h>
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]);
}
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
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 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.
#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 findLFUPage() {
int min_frequency = INT_MAX;
int min_frequency_index = -1;
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");
}
int main() {
initializeFrames();
int page_number;
printf("Enter the number of pages: ");
scanf("%d", &num_pages);
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);
}
}
return 0;
}