0% found this document useful (0 votes)
741 views42 pages

Os Lab Manual R22

The document outlines the syllabus for the DS406PC Operating Systems Lab course, including prerequisites, co-requisites, course objectives, and outcomes. It details various experiments involving C programming to simulate operating system concepts such as CPU scheduling algorithms, interprocess communication, and memory management techniques using Unix system calls. Additionally, it provides algorithms and sample programs for implementing these concepts in C.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
741 views42 pages

Os Lab Manual R22

The document outlines the syllabus for the DS406PC Operating Systems Lab course, including prerequisites, co-requisites, course objectives, and outcomes. It details various experiments involving C programming to simulate operating system concepts such as CPU scheduling algorithms, interprocess communication, and memory management techniques using Unix system calls. Additionally, it provides algorithms and sample programs for implementing these concepts in C.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 42

DS406PC: OPERATING SYSTEMS LAB

B.Tech. II Year II Sem. LTPC


0021

Prerequisites: A course on “Programming for Problem Solving”, A course on


“Computer Organization and Architecture”.

Co-requisite: A course on “Operating Systems”. Course Objectives:

 To provide an understanding of the design aspects of operating system concepts


through simulation
 Introduce basic Unix commands, system call interface for process management,
interprocess communication and I/O in Unix
Course Outcomes:
 Simulate and implement operating system concepts such as scheduling, deadlock
management, file management and memory management.
 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 c) Round Robin d) priority
2. Write programs using the I/O system calls of UNIX/LINUX operating system
(open, read, write, close, fcntl, seek, stat, opendir, readdir)
3. Write a C program to simulate Bankers Algorithm for Deadlock Avoidance and
Prevention.
4. Write a C program to implement the Producer – Consumer problem using
semaphores using
UNIX/LINUX system calls.
5. Write C programs to illustrate the following IPC mechanisms a) Pipes b) FIFOs c)
Message Queues d) Shared Memory
6. Write C programs to simulate the following memory management techniques a)
Paging b) Segmentation
7. Write C programs to simulate Page replacement policies a) FCFS b) LRU c)
Optimal

REFERENCE BOOKS:
1. Operating Systems – Internals and Design Principles, William Stallings, Fifth Edition–
2005, Pearson Education/PHI
2. Operating System - A Design Approach-Crowley, TMH.
3. Modern Operating Systems, Andrew S Tanenbaum, 2nd edition, Pearson/PHI
4. UNIX Programming Environment, Kernighan and Pike, PHI/Pearson Education
5. UNIX Internals: The New Frontiers, U. Vahalia, Pearson Education
1. Write C programs to simulate the following CPU Scheduling algorithms.
a) FCFS
b) SJF
c) Round Robin
d) Priority

a)FCFS (First Come First Serve)


Aim: Write a C program to implement the various process scheduling mechanisms such as
FCFS scheduling.

DESCRIPTION:
To calculate the average waiting time using the FCFS algorithm first the waiting time of the
first process is kept zero and the waiting time of the second process is the burst time of the
first process and the waiting time of the third process is the sum of the burst times of the
first and the second process and so on. After calculating all the waiting times the average
waiting time is calculated as the average of all the waiting times. FCFS mainly says first
come first serve the algorithm which came first will be served first.

Algorithm:
1: Start the process
2: Accept the number of processes in the ready Queue
3: For each process in the ready Q, assign the process id and accept the CPU burst time
4: Set the waiting of the first process as ‘0’ and its burst time as its turn around time
5: for each process in the Ready Q calculate
a. Waiting time for process(n)= waiting time of process (n-1) + Burst time of process(n-1)
b. Turnaround time for Process(n)= waiting time of Process(n)+ Burst time for process(n)
6: Calculate
a. Average waiting time = Total waiting Time / Number of process
b. Average Turnaround time = Total Turnaround Time / Number of process
7: Stop the process

PROGRAM :
#include<stdio.h>
int main()
{
int bt[20],p[20],wt[20],tat[20],i,j,n,total=0,pos,temp;
float avg_wt,avg_tat;
printf("Enter number of process:");
scanf("%d",&n);
printf("\nEnter Burst Time:\n");
for(i=0;i<n;i++)
{
printf("p % d:",i+1);
scanf("%d",&bt[i]);
p[i]=i+1; //contains process number
}
wt[0]=0; //waiting time for first process will be zero
//calculate waiting time
for(i=1;i<n;i++)
{
wt[i]=0;
for(j=0;j<i;j++)
wt[i]+=bt[j];
total+=wt[i];
}
avg_wt=(float)total/n; //average waiting time
total=0;

printf("\nProcess\t Burst Time \tWaiting Time\tTurnaround Time");


for(i=0;i<n;i++)
{
tat[i]=bt[i]+wt[i]; //calculate turnaround time
total+=tat[i];
printf("\np%d\t\t %d\t\t %d\t\t\t%d",p[i],bt[i],wt[i],tat[i]);
}
avg_tat=(float)total/n; //average turnaround time
printf("\n\nAverage Waiting Time=%f",avg_wt);
printf("\nAverage Turnaround Time=%f\n",avg_tat);
}

OUTPUT :
b) SJF (Shortest Job First)
Aim: Write a C program to implement the various process scheduling
mechanisms such as SJF scheduling.

Algorithm:
1: Start the process
2: Accept the number of processes in the ready Queue
3: For each process in the ready Q, assign the process id and accept the CPU
burst time 4: Start
the Ready Q according the shortest Burst time by sorting according to lowest to
highest burst
time.
5: Set the waiting time of the first process as ‘0’ and its turnaround time as its
burst time.
6: For each process in the ready queue, calculate
(a) Waiting time for process(n)= waiting time of process (n-1) + Burst time of
process(n-1)
(b) Turn around time for Process(n)= waiting time of Process(n)+ Burst time for
process(n)
7: Calculate
(c) Average waiting time = Total waiting Time / Number of process
Average Turnaround time = Total Turnaround Time / Number of process
8: Stop the process

Program:
#include<stdio.h>
int main()
{
int bt[20],p[20],wt[20],tat[20],i,j,n,total=0,pos,temp;
float avg_wt,avg_tat;
printf("Enter number of process:");
scanf("%d",&n);
printf("\nEnter Burst Time:\n");
for(i=0;i<n;i++)
{
printf("p%d:",i+1);
scanf("%d",&bt[i]);
p[i]=i+1; //contains process number
}
//sorting burst time in ascending order using selection sort
for(i=0;i<n;i++)
{
pos=i;
for(j=i+1;j<n;j++)
{
if(bt[j]<bt[pos])
pos=j;
}
temp=bt[i];
bt[i]=bt[pos];
bt[pos]=temp;
temp=p[i];
p[i]=p[pos];
p[pos]=temp;
}
wt[0]=0; //waiting time for first process will be zero
//calculate waiting time
for(i=1;i<n;i++)
{
wt[i]=0;
for(j=0;j<i;j++)
wt[i]+=bt[j];
total+=wt[i];
}
avg_wt=(float)total/n; //average waiting time
total=0;
printf("\nProcess\t Burst Time \tWaiting Time\tTurnaround Time");
for(i=0;i<n;i++)
{
tat[i]=bt[i]+wt[i]; //calculate turnaround time
total+=tat[i];
printf("\np%d\t\t %d\t\t %d\t\t\t%d",p[i],bt[i],wt[i],tat[i]);
}
avg_tat=(float)total/n; //average turnaround time
printf("\n\nAverage Waiting Time=%f",avg_wt);
printf("\nAverage Turnaround Time=%f\n",avg_tat);
}

OUTPUT:
c) Round Robin
Aim: Write a C program to implement the various process scheduling
mechanisms such as Round Robin Scheduling.

Algorithm
1: Start the process
2: Accept the number of processes in the ready Queue and time quantum (or)
time slice
3: For each process in the ready Q, assign the process id and accept the CPU
burst time
4: Calculate the no. of time slices for each process where
No. of time slice for process(n) = burst time process(n)/time slice
5: If the burst time is less than the time slice then the no. of time slices =1.
6: Consider the ready queue is a circular Q, calculate
(a) Waiting time for process(n) = waiting time of process(n-1)+ burst time of
process(n-1 ) + the time difference in getting the CPU from process(n-1)
(b) Turn around time for process(n) = waiting time of process(n) + burst time of
process(n)+ the time difference in getting CPU from process(n).
7: Calculate
(a) Average waiting time = Total waiting Time / Number of process
(b) Average Turnaround time = Total Turnaround Time / Number of process Step
8: Stop the process

Program:
#include<stdio.h>
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,atat;
printf("enter the number of processes");
scanf("%d",&n);
printf("enter the burst time of each process /n");
for(i=0;i<n;i++)
{
printf(("p%d",i+1);
scanf("%d",&bt[i]);
st[i]=bt[i];
}
printf("enter the 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("process no\t burst time\t waiting time\t turnaround time\n");
for(i=0;i<n;i++)
printf("%d\t\t %d\t\t %d\t\t %d\n",i+1,bt[i],wt[i],tat[i]);
printf("avg wt time=%f,avg turn around time=%f",awt,atat);
}

OUTPUT :
d) Priority

Aim: Write a C program to implement the various process scheduling


mechanisms such as Priority Scheduling.

Algorithm:
1: Start the process
2: Accept the number of processes in the ready Queue
3: For each process in the ready Q, assign the process id and accept the CPU
burst time 4: Sort the ready queue according to the priority number.
5: Set the waiting of the first process as ‘0’ and its burst time as its turn around
time
6: For each process in the Ready Q calculate
Waiting time for process(n)= waiting time of process (n-1) + Burst time of
process(n-1)
Turn around time for Process(n)= waiting time of Process(n)+ Burst time for
process(n)
7. Calculate
(g) Average waiting time = Total waiting Time / Number of process
(h) Average Turnaround time = Total Turnaround Time / Number of process Step
8: Stop the process

Program:
#include<stdio.h>
int main()
{
int bt[20],p[20],wt[20],tat[20],pri[20],i,j,k,n,total=0,pos,temp;
float avg_wt,avg_tat;
printf("Enter number of process:");
scanf("%d",&n);
printf("\nEnter Burst Time:\n");
for(i=0;i<n;i++)
{
printf("p%d:",i+1);
scanf("%d",&bt[i]);
p[i]=i+1; //contains process number
}
printf(" enter priority of the process ");
for(i=0;i<n;i++)
{
p[i] = i;
//printf("Priority of Process");
printf("p%d ",i+1);
scanf("%d",&pri[i]);
}
for(i=0;i<n;i++)
for(k=i+1;k<n;k++)
if(pri[i] > pri[k])
{
temp=p[i];
p[i]=p[k];
p[k]=temp;
temp=bt[i];
bt[i]=bt[k];
bt[k]=temp;
temp=pri[i];
pri[i]=pri[k];
pri[k]=temp;
}

wt[0]=0; //waiting time for first process will be zero


//calculate waiting time
for(i=1;i<n;i++)
{
wt[i]=0;
for(j=0;j<i;j++)
wt[i]+=bt[j];
total+=wt[i];
}
avg_wt=(float)total/n; //average waiting time
total=0;
printf("\nProcess\t Burst Time \tPriority \tWaiting Time\tTurnaround Time");
for(i=0;i<n;i++)
{
tat[i]=bt[i]+wt[i]; //calculate turnaround time
total+=tat[i];
printf("\np%d\t\t %d\t\t %d\t\t %d\t\t\t%d",p[i],bt[i],pri[i],wt[i],tat[i]);
}
avg_tat=(float)total/n; //average turnaround time
printf("\n\nAverage Waiting Time=%f",avg_wt);
printf("\nAverage Turnaround Time=%f\n",avg_tat);
}

OUTPUT :
2. Write programs using the I/O system calls of UNIX/LINUX operating
system (open, read, write, close, fcntl, seek, stat, opendir, readdir)

Aim: C program using open, read, write, close system calls


Theory:
There are 5 basic system calls that Unix provides for file I/O.
1. Create: Used to Create a new empty file
Syntax :int creat(char *filename, mode_t mode)
filename : name of the file which you want to create
mode : indicates permissions of new file.
2. open: Used to Open the file for reading, writing or both.
Syntax: int open(char *path, int flags [ , int mode ] );
Path : path to file which you want to use
flags : How you like to use
O_RDONLY: read only, O_WRONLY: write only, O_RDWR: read and write,
O_CREAT: create file if it doesn’t exist, O_EXCL: prevent creation if it already
exists
3. close: Tells the operating system you are done with a file descriptor and
Close the file which pointed by fd.
Syntax: int close(int fd);
fd :file descriptor
4. read: From the file indicated by the file descriptor fd, the read() function
reads cnt bytes of input into the memory area indicated by buf. A successful
read() updates the access time for the file.
Syntax: int read(int fd, char *buf, int size);
fd: file descripter
buf: buffer to read data from
cnt: length of buffer

5. write: Writes cnt bytes from buf to the file or socket associated with fd. cnt
should not be greater than INT_MAX (defined in the limits.h header file). If cnt is
zero, write() simply returns 0 without attempting any other action.
Syntax: int write(int fd, char *buf, int size);
fd: file descripter
buf: buffer to write data to
cnt: length of buffer
*File descriptor is integer that uniquely identifies an open file of the process

Algorithm :
1. Star the program.
2. Open a file for O_RDWR for R/W,O_CREATE for creating a file ,O_TRUNC for
truncate
a file.
3. Using getchar(), read the character and stored in the string[] array.
4. The string [] array is write into a file close it.
5. Then the first is opened for read only mode and read the characters and
displayed it and
close the file.
6. Stop the program.
Program :
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
int main()
{
int n,i=0;
int f1,f2;
char c,strin[100];
f1=open("data",O_RDWR|O_CREAT|O_TRUNC);
while((c=getchar())!='\n')
{
strin[i++]=c;
}
strin[i]='\0';
write(f1,strin,i);
close(f1);
f2=open("data",O_RDONLY);
read(f2,strin,0);
printf("\n%s\n",strin);
close(f2);
return 0;
}

Output:
Hai
Hai
b) Aim: C program using lseek

Theory:
lseek is a system call that is used to change the location of the read/write
pointer of a file descriptor.
The location can be set either in absolute or relative terms.
Syntax : off_t lseek(int fildes, off_t offset, int whence);
int fildes : The file descriptor of the pointer that is going to be moved.
off_t offset : The offset of the pointer (measured in bytes).
int whence : Legal values for this variable are provided at the end which are
SEEK_SET (Offset is to be measured in absolute terms), SEEK_CUR (Offset is to
be measured relative to the current location of the pointer), SEEK_END (Offset
is to be measured relative to the end of the file)

Algorithm:
1. Start the program
2. Open a file in read mode
3. Read the contents of the file
4. Use lseek to change the position of pointer in the read process
5. Stop

Program:
#include<stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
int main()
{
int file=0;
if((file=open("testfile.txt",O_RDONLY)) < -1)
return 1;
char buffer[19];
if(read(file,buffer,19) != 19) return 1;
printf("%s\n",buffer);
if(lseek(file,10,SEEK_SET) < 0) return 1;
if(read(file,buffer,19) != 19) return 1;
printf("%s\n",buffer);
return 0;
}

OUTPUT :
c) Aim: C program using opendir(), closedir(), readdir()

Theory:
The following are the various operations using directories
1. Creating directories.
Syntax : int mkdir(const char *pathname, mode_t mode);
2. The ‘pathname’ argument is used for the name of the directory.
3. Opening directories
Syntax : DIR *opendir(const char *name);
4. Reading directories.
Syntax: struct dirent *readdir(DIR *dirp);
5. Removing directories.
Syntax: int rmdir(const char *pathname);
6. Closing the directory.
Syntax: int closedir(DIR *dirp);
7. Getting the current working directory.
Syntax: char *getcwd(char *buf, size_t size);

Algorithm:
1. Start the program
2. Print a menu to choose the different directory operations
3. To create and remove a directory ask the user for name and create and
remove the same
respectively.
4. To open a directory check whether directory exists or not. If yes open the
directory .If it
does not exists print an error message.
5. Finally close the opened directory.
6. Stop

Program:
#include<stdio.h>
#include<fcntl.h>
#include<dirent.h>
main()
{
char d[10]; int c,op; DIR *e;
struct dirent *sd;
printf("**menu**\n1.create dir\n2.remove dir\n 3.read dir\n enter ur choice");
scanf("%d",&op);
switch(op)
{
case 1: printf("enter dir name\n"); scanf("%s",&d);
c=mkdir(d,777);
if(c==1)
printf("dir is not created");
else
printf("dir is created"); break;
case 2: printf("enter dir name\n"); scanf("%s",&d);
c=rmdir(d);
if(c==1)
printf("dir is not removed");
else
printf("dir is removed"); break;
case 3: printf("enter dir name to open");
scanf("%s",&d);
e=opendir(d);
if(e==NULL)
printf("dir does not exist"); else
{
printf("dir exist\n"); while((sd=readdir(e))!=NULL) printf("%s\t",sd->d_name);
}
closedir(e);
break;
}
}

OUTPUT :

dir is created
3. Write a C program to simulate Bankers Algorithm for Deadlock
Avoidance and Prevention

a) Aim: Data structures


1. n- Number of process, m-number of resource types.
2. Available: Available[j]=k, k – instance of resource type Rj is available.
3. Max: If max [i, j]=k, Pi may request at most k instances resource Rj.
4. Allocation: If Allocation [i, j]=k, Pi allocated to k instances of resource Rj
5. Need: If Need[I, j]=k, Pi may need k more instances of resource type Rj,
6. Need [I, j] =Max [I, j]-Allocation [I, j];

Safety Algorithm
1. Work and Finish be the vector of length m and n respectively,
Work=Available and
Finish[i] =False.
2. Find an i such that both
3. Finish[i] =False
4. Need<=Work
5. If no such I exist go to step 4.
6. work=work+Allocation, Finish[i] =True;
7. If Finish [1] =True for all I, then the system is in safe state.

Resource request algorithm


1. Let Request i be request vector for the process Pi, If request i=[j]=k, then
process Pi wants
k instances of resource type Rj.
2. If Request<=Need I go to step 2. Otherwise raise an error condition.
3. If Request<=Available go to step 3. Otherwise Pi must since the resources
are available.
4. Have the system pretend to have allocated the requested resources to
process Pi by
modifying the state as follows;
5. Available=Available-Request I;
6. Allocation I =Allocation+Request I;
7. 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, the Pi
must wait for Request i and the old resource-allocation state is restore

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 is possible to allocate.
6. If it is possible then the system is in safe state.
7. Else system is not in safety state.
8. If the new request comes then check that the system is in safety.
9. Or not if we allow the request.
10. Stop the program.
Program:
#include<stdio.h>
int main ()
{
int allocated[15][15], max[15][15], need[15][15], avail[15], tres[15],
work[15], flag[15];
int pno, rno, i, j, prc, count, t, total;
count = 0;
//clrscr ();
printf ("\n Enter number of process:");
scanf ("%d", &pno);
printf ("\n Enter number of resources:");
scanf ("%d", &rno);
for (i = 1; i <= pno; i++)
{
flag[i] = 0;
}
printf ("\n Enter total numbers of each resources:");
for (i = 1; i <= rno; i++)
scanf ("%d", &tres[i]);
printf ("\n Enter Max resources for each process:");
for (i = 1; i <= pno; i++)
{
printf ("\n for process %d:", i);
for (j = 1; j <= rno; j++)
scanf ("%d", &max[i][j]);
}
printf ("\n Enter allocated resources for each process:");
for (i = 1; i <= pno; i++)
{
printf ("\n for process %d:", i);
for (j = 1; j <= rno; j++)
scanf ("%d", &allocated[i][j]);
}
printf ("\n available resources:\n");
for (j = 1; j <= rno; j++)
{
avail[j] = 0;
total = 0;
for (i = 1; i <= pno; i++)
{
total += allocated[i][j];
}
avail[j] = tres[j] - total;
work[j] = avail[j];
printf (" %d \t", work[j]);
}
do
{
for (i = 1; i <= pno; i++)
{
for (j = 1; j <= rno; j++)
{
need[i][j] = max[i][j] - allocated[i][j];
}
}
printf ("\n Allocated matrix Max need");
for (i = 1; i <= pno; i++)
{
printf ("\n");
for (j = 1; j <= rno; j++)
{
printf ("%4d", allocated[i][j]);
}
printf ("|");
for (j = 1; j <= rno; j++)
{
printf ("%4d", max[i][j]);
}
printf ("|");
for (j = 1; j <= rno; j++)
{
printf ("%4d", need[i][j]);
}
}
prc = 0;
for (i = 1; i <= pno; i++)
{
if (flag[i] == 0)
{
prc = i;
for (j = 1; j <= rno; j++)
{
if (work[j] < need[i][j])
{
prc = 0;
break;
}
}
}
if (prc != 0)
break;
}
if (prc != 0)
{
printf ("\n Process %d completed", i);
count++;
printf ("\n Available matrix:");
for (j = 1; j <= rno; j++)
{
work[j] += allocated[prc][j];
allocated[prc][j] = 0;
max[prc][j] = 0;
flag[prc] = 1;
printf (" %d", work[j]);
}
}
}
while (count != pno && prc != 0);
if (count == pno)
printf ("\nThe system is in a safe state!!");
else
printf ("\nThe system is in an unsafe state!!");
return 0;
}

OUTPUT :
b) Aim : Write a C program to simulate Bankers Algorithm for Deadlock
Prevention

Algorithm:
1. Start
2. Attacking Mutex condition : never grant exclusive access. but this may not
be possible for several resources.
3. Attacking preemption: 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. eg. 2- phase locking 34
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. ie. 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],i,j,p,r,finish[10]={0},flag=0;
main( )
{
printf("\n SIMULATION OF DEADLOCK PREVENTION \n ");
printf("Enter no. of processes, resources\n ");
scanf("%d%d",&p,&r);
printf("Enter allocation matrix");
for(i=0;i<p;i++)
for(j=0;j<r;j++)
scanf("%d",&alloc[i][j]);
printf("\n enter max matrix");
for(i=0;i<p;i++) /*reading the maximum matrix and availale matrix*/
for(j=0;j<r;j++)
scanf("%d",&max[i][j]);
printf(" \n enter available matrix");
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)
{if(finish[i]!=1)
{
printf("\n Failing :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("\n By allocating required resources to process %d dead lock is prevented
",i);
printf("\n 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("\n dead lock is prevented by allocating needed resources");
printf(" \n failing: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("\n AVOIDING ANY ONE OF THE CONDITION, U CAN PREVENT
DEADLOCK");
}
}
}
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;
}
}
}
OUTPUT :
4. Write a C program to implement the Producer – Consumer problem
using semaphores using UNIX/LINUX system calls.
Aim: Write a C program to implement the Producer – Consumer problem using
semaphores using UNIX/LINUX system calls.

Algorithm:
1. The Semaphore mutex, full & empty are initialized.
2. In the case of producer process
3. Produce an item in to temporary variable.
If there is empty space in the buffer check the mutex value for enter into the
critical section. If the mutex value is 0, allow the producer to add value in the
temporary variable to the buffer.
4. In the case of consumer process
i) It should wait if the buffer is empty
ii) If there is any item in the buffer check for mutex value, if the mutex==0,
remove item from buffer
iii) Signal the mutex value and reduce the empty value by 1.
iv) Consume the item.
5. Print the result

Program:
#include<stdio.h>
#include<stdlib.h>
int mutex = 1, full = 0, empty = 3, x = 0;
int main ()
{
int n;
void producer ();
void consumer ();
int wait (int);
int signal (int);
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 :
5. Write C programs to illustrate the following IPC mechanisms
a) Pipes b) FIFOs c) Message Queues d) Shared Memory

AIM: Write a C program to illustrate the Pipes IPC mechanism

PROGRAM
#include <stdio.h>
#include <unistd.h>
#define MSGSIZE 16
char* msg1 = "hello, world #1";
char* msg2 = "hello, world #2";
char* msg3 = "hello, world #3";
int main()
{
char inbuf[MSGSIZE];
int p[2], i;
if (pipe(p) < 0)
exit(1);
/* continued */
/* write pipe */
write(p[1], msg1, MSGSIZE);
write(p[1], msg2, MSGSIZE);
write(p[1], msg3, MSGSIZE);
for (i = 0; i < 3; i++) {
/* read pipe */
read(p[0], inbuf, MSGSIZE);
printf("% s\n", inbuf);
}
return 0;
}

Output:
hello, world #1
hello, world #2
hello, world #3
b) AIM : 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()
{
int fd;
// FIFO file path
char * myfifo = "/tmp/myfifo";
// Creating the named file(FIFO)
// mkfifo(<pathname>, <permission>)
mkfifo(myfifo, 0666);
char arr1[80], arr2[80];
while (1)
{
// Open FIFO for write only
fd = open(myfifo, O_WRONLY);
// Take an input arr2ing from user.
// 80 is maximum length
fgets(arr2, 80, stdin);
// Write the input arr2ing on FIFO
// and close it
write(fd, arr2, strlen(arr2)+1);
close(fd);
// Open FIFO for Read only
fd = open(myfifo, O_RDONLY);
// Read from FIFO
read(fd, arr1, sizeof(arr1));
// Print the read message
printf("User2: %s\n", arr1);
close(fd);
}
return 0;
}
c) AIM : 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>
// structure for message queue
struct mesg_buffer {
long mesg_type;
char mesg_text[100];
} message;
int main()
{
key_t key;
int msgid;
// ftok to generate unique key
key = ftok("progfile", 65);
// msgget creates a message queue
// and returns identifier
msgid = msgget(key, 0666 | IPC_CREAT);
message.mesg_type = 1;
printf("Write Data : ");
gets(message.mesg_text);
// msgsnd to send message
msgsnd(msgid, &message, sizeof(message), 0);
// display the message
printf("Data send is : %s \n", message.mesg_text);
return 0;
}

// C Program for Message Queue (Reader Process)


#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// structure for message queue
struct mesg_buffer {
long mesg_type;
char mesg_text[100];
} message;
int main()
{
key_t key;
int msgid;
// ftok to generate unique key
key = ftok("progfile", 65);
// msgget creates a message queue
// and returns identifier
msgid = msgget(key, 0666 | IPC_CREAT);
// msgrcv to receive message
msgrcv(msgid, &message, sizeof(message), 1, 0);
// display the message
printf("Data Received is : %s \n",
message.mesg_text);
// to destroy the message queue
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
d)AIM : 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_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
char *str = (char*) shmat(shmid,(void*)0,0);
cout<<"Write Data : ";
gets(str);
printf("Data written in memory: %s\n",str);
//detach from shared memory
shmdt(str);
return 0;
}

//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_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
char *str = (char*) shmat(shmid,(void*)0,0);
printf("Data read from memory: %s\n",str);
//detach from shared memory
shmdt(str);
// destroy the shared memory
shmctl(shmid,IPC_RMID,NULL);
return 0;
}

OUTPUT:
./writer

Write data : Trinity College of Engineering & Technology


Data written in memory :Trinity College of Engineering & Technology

./reader

Data read from memory : Trinity College of Engineering & Technology

6. Write C programs to simulate the following memory management


techniques a) Paging b) Segmentation
AIM : 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>
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("\nEnter the page size -- "); scanf("%d",&ps);
nop = ms/ps;
printf("\nThe no. of pages available in memory are -- %d ",nop);
printf("\nEnter number of processes -- "); scanf("%d",&np);
rempages = nop;
for(i=1;i<=np;i++)
{
printf("\nEnter no. of pages required for p[%d]-- ",i); scanf("%d",&s[i]);
if(s[i] >rempages)
{
printf("\nMemory is Full"); break;
}
rempages = rempages - s[i];
printf("\nEnter pagetable for p[%d] -,i);
for(j=0;j<s[i];j++)
scanf("%d",&fno[i][j]);
}
printf("\nEnter Logical Address to find Physical Address ");
printf("\nEnter process no. and pagenumber and offset ");
scanf("%d %d %d",&x,&y, &offset);
if(x>np || y>=s[i] || offset>=ps)
printf("\nInvalid Process or Page Number or offset");
else
{
pa=fno[x][y]*ps+offset;
printf("\nThe Physical Address is -- %d",pa);
}
getch();
}

INPUT
Enter the memory size – 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 pagetable for p[1] --- 8 6 9 5
Enter no. of pages required for p[2] -- 5
Enter pagetable 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 pagenumber and offset -- 2 3 60
The Physical Address is – 760

b) AIM: To implement the memory management policy-segmentation


PROGRAM LOGIC:
1. Start the program.
2. Get the number of segments.
3. Get the base address and length for each segment.
4. Get the logical address.
5. Check whether the segment number is within the limit, if not display the
error message.
6. Check whether the byte reference is within the limit, if not display the error
message.
7. Calculate the physical memory and display it.
8. Stop the program

PROGRAM :
#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;
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\t Do U want to Continue(Y/N)");
flushall();
scanf("%c",&ch);
}while (ch == 'Y' || ch == 'y' );
getch();
}

INPUT AND OUTPUT:


Enter the size of the segment table: 3
Enter the information about segment: 1
Enter the base Address: 4
Enter the Limit: 5
Enter the 4 address Value: 11
Enter the 5 address Value: 12
Enter the 6 address Value: 13
Enter the 7 address Value: 14
Enter the 8 address Value: 15
Enter the information about segment: 2
Enter the base Address: 5
Enter the Limit: 4
Enter the 5 address Value: 21
Enter the 6 address Value: 31
Enter the 7 address Value: 41
Enter the 8 address Value: 51
Enter the information about segment: 3
Enter the base Address: 3
Enter the Limit: 4
Enter the 3 address Value: 31
Enter the 4 address Value: 41
Enter the 5 address Value: 41
Enter the 6 address Value: 51
SEGMENT TABLE SEG.NO BASE ADDRESS LIMIT
145
254
334
Enter the logical Address: 3
Logical Address is: 3
Mapped Physical address is: 3
The value is: 31
Do U want to Continue(Y/N)
SEGMENT TABLE SEG.NO BASE ADDRESS LIMIT
145
254
334
Enter the logical Address: 1
Logical Address is: 1
Mapped Physical address is: 4
The value is: 11 Do U want to Continue(Y/N)

7. Write C programs to simulate Page replacement policies a) FCFS b)


LRU c) Optimal
DESCRIPTION
Page replacement is basic to demand paging. It completes the separation
between logical memory and physical memory. With this mechanism, an
enormous virtual memory can be provided for programmers on a smaller
physical memory. There are many different page-replacement algorithms.
Every operating system probably haS its own replacement scheme. A FIFO
replacement algorithm associates with each page the time when that page
was brought into memory. When a page must be replaced, the oldest page is
chosen. If the recent past is used as an approximation of the near future, then
the page that has not been used for the longest period of time can
be replaced. This approach is the Least Recently Used (LRU) algorithm. LRU
replacement associates with each page the time of that page's last use. When
a page must be replaced, LRU chooses the page that has not been
used for the longest period of time. Least frequently used (LFU) page-
replacement algorithm requires that the page with the smallest count be
replaced. The reason for this selection is that an actively used page should
have a large reference count.

a) FIFO PAGE REPLACEMENT ALGORITHM


#include<stdio.h>
#include<conio.h>
main()
{
int i, j, k, f, pf=0, count=0, rs[25], m[10], n;
clrscr();
printf("\n Enter the length of reference string -- ");
scanf("%d",&n);
printf("\n Enter the reference string -- ");
for(i=0;i<n;i++)
scanf("%d",&rs[i]);
printf("\n Enter no. of frames -- ");
scanf("%d",&f);
for(i=0;i<f;i++)
m[i]=-1;
printf("\n The Page Replacement Process is -- \n");
for(i=0;i<n;i++)
{
for(k=0;k<f;k++)
{
}
if(k==f)
{
}
if(m[k]==rs[i])
break;
m[count++]=rs[i];
pf++;
for(j=0;j<f;j++)
printf("\t%d",m[j]);
if(k==f)
printf("\tPF No. %d",pf);
printf("\n");
if(count==f)
count=0;
}
printf("\n The number of Page Faults using FIFO are %d",pf);
getch();

INPUT
Enter the length of reference string – 20
Enter the reference string -- 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
Enter no. of frames – 3

OUTPUT
The Page Replacement Process is –
7 -1 -1 PF No. 1
7 0 -1 PF No. 2
7 0 1 PF No. 3
2 0 1 PF No. 4
201
2 3 1 PF No. 5
2 3 0 PF No. 6
4 3 0 PF No. 7
4 2 0 PF No. 8
4 2 3 PF No. 9
0 2 3 PF No. 10
023
023
0 1 3 PF No. 11
0 1 2 PF No. 12
012
012
7 1 2 PF No. 13
7 0 2 PF No. 14
7 0 1 PF No. 15
The number of Page Faults using FIFO are 15

b) LRU PAGE REPLACEMENT ALGORITHM


#include<stdio.h>
#include<conio.h>
main()
{
int i, j , k, min, rs[25], m[10], count[10], flag[25], n, f, pf=0, next=1;
clrscr();
printf("Enter the length of reference string -- ");
scanf("%d",&n);
printf("Enter the reference string -- ");
for(i=0;i<n;i++)
{
scanf("%d",&rs[i]);
flag[i]=0;
}
printf("Enter the number of frames -- ");
scanf("%d",&f);
for(i=0;i<f;i++)
{
count[i]=0;
m[i]=-1;
}
printf("\nThe Page Replacement process is -- \n");
for(i=0;i<n;i++)
{
for(j=0;j<f;j++)
{
if(m[j]==rs[i])
{
flag[i]=1;
}
}
if(flag[i]==0)
{
count[j]=next;
next++;
if(i<f)
{
}
else
{
}
pf++;
}
m[i]=rs[i];
count[i]=next;
next++;
min=0;
for(j=1;j<f;j++)
if(count[min] > count[j])
min=j;
m[min]=rs[i];
count[min]=next;
next++;
for(j=0;j<f;j++)
printf("%d\t", m[j]);
if(flag[i]==0)
printf("PF No. -- %d" , pf);
printf("\n");
}
printf("\nThe number of page faults using LRU are %d",pf);
getch();
}

INPUT
Enter the length of reference string -- 20
Enter the reference string -- 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
Enter the number of frames – 3

OUTPUT
The Page Replacement process is --
7 -1 -1 PF No. -- 1
7 0 -1 PF No. -- 2
7 0 1 PF No. -- 3
2 0 1 PF No. -- 4
201
2 0 3 PF No. -- 5
203
4 0 3 PF No. – 6
4 0 2 PF No. – 7
4 3 2 PF No. – 8
0 3 2 PF No. – 9
032
032
1 3 2 PF No. – 10
132
1 0 2 PF No. – 11
102
1 0 7 PF No. – 12
107
39
107
The number of page faults using LRU are 12

c) Optimal
DESCRIPTION
Optimal page replacement algorithm has the lowest page-fault rate of all
algorithms and will never suffer from Belady's anomaly. The basic idea is to
replace the page that will not be used for the longest period of time. Use
of this page-replacement algorithm guarantees the lowest possible page fault
rate for a fixed number of frames. Unfortunately, the optimal page-replacement
algorithm is difficult to implement, because it requires future knowledge of the
reference string.

PROGRAM
#include<stdio.h>
int n;
main()
{
int seq[30],fr[5],pos[5],find,flag,max,i,j,m,k,t,s;
int count=1,pf=0,p=0;
float pfr;
clrscr();
printf("Enter maximum limit of the sequence: ");
scanf("%d",&max);
printf("\nEnter the sequence: ");
for(i=0;i<max;i++)
scanf("%d",&seq[i]);
printf("\nEnter no. of frames: ");
scanf("%d",&n);
fr[0]=seq[0];
pf++;
printf("%d\t",fr[0]);
i=1;
while(count<n)
{
flag=1;
p++;
for(j=0;j<i;j++)
{
if(seq[i]==seq[j])
flag=0;
}
if(flag!=0)
{
}
i++;
}
fr[count]=seq[i];
printf("%d\t",fr[count]);
count++;
pf++;
printf("\n");
for(i=p;i<max;i++)
{
flag=1;
for(j=0;j<n;j++)
{
if(seq[i]==fr[j])
flag=0;
}
if(flag!=0)
{
for(j=0;j<n;j++)
{
m=fr[j];
for(k=i;k<max;k++)
{
if(seq[k]==m)
{
}
else
}
}
pos[j]=k;
break;
pos[j]=1;
for(k=0;k<n;k++)
{
if(pos[k]==1)
flag=0;
}
if(flag!=0)
s=findmax(pos);
if(flag==0)
{
for(k=0;k<n;k++)
{
if(pos[k]==1)
{
s=k;
break;
}
}
}
fr[s]=seq[i];
for(k=0;k<n;k++)
printf("%d\t",fr[k]);
pf++;
printf("\n");
}
}
pfr=(float)pf/(float)max;
printf("\nThe no. of page faults are %d",pf);
printf("\nPage fault rate %f",pfr);
getch();
}
int findmax(int a[])
{
int max,i,k=0;
max=a[0];
for(i=0;i<n;i++)
{
if(max<a[i])
{
}

INPUT
}
}
return k;
max=a[i];
k=i;
Enter number of page references -- 10
Enter the reference string -- 1 2 3 4 5 2 5 2 5 1 4 3
Enter the available no. of frames – 3

OUTPUT
The Page Replacement Process is –
1 -1 -1 PF No. 1
1 2 -1 PF No. 2
1 2 3 PF No. 3
4 2 3 PF No. 4
5 2 3 PF No. 5
523
523
5 2 1 PF No. 6
5 2 4 PF No. 7
5 2 3 PF No. 8
Total number of page faults -- 8

You might also like