0% found this document useful (0 votes)
20 views57 pages

Final Os Student

Uploaded by

pranayande1032
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)
20 views57 pages

Final Os Student

Uploaded by

pranayande1032
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/ 57

CMR ENGINEERING COLLEGE

(UGC AUTONOMOUS)
(Approved by AICTE-New Delhi,
Affiliated to JNTUH) Kondlakoya(v),
Medchal Road, Hyderabad - 501401

Department Of Computer Science and


Engineering–Data Science

STUDENT MANUAL
Name of Lab : Operating System LAB
Subject Code : DS303PC

Class : II Year I Sem

Regulation : R22

Academic Year : 2024-2025


Department Vision

 To create the next generation and globally competent data scientists/data


engineers in the field of Data Science domain by providing quality
engineering education along with cutting edge technologies.

Department Mission

 To provide value based engineering education through continues learning


and research by imparting solid foundation in applied mathematics,
algorithms and programming paradigms to build software models and
simulations.

 To develop concepts building, logical and problem solving skills of


graduates to address current global challenges of industry and society.
 To offer excellence in teaching and learning process, industry collaboration
activities and research to mould graduates into industry ready professionals
LABORATORY INSTRUCTIONS:

1. Students should report to the concerned labs as per the time table.

2. Students should attend the Laboratory classes in time. Late comers shall not be permitted
to enter the Laboratory and they are likely to lose attendance.

3. The students should come to the Laboratories with the prescribed uniform.
(Blue/White apron with shoes)

4. Student without Identity Cards are not allowed to the Laboratory classes.

5. Students should be present in the labs for the total scheduled duration.
6. Students should bring an observation book of about 100 pages and should enter the
Algorithm, Flowchart and Program into that book.

7. If any student is absent in the Lab, the concerned faculty has to inform the mentor, in turn
has to inform the parents
8. The assigned second faculty must ask the viva questions for day-to-day evaluation.
9. Students are required to write the Flowchart, Algorithm & Program before coming to
the Lab.
10. Students are instructed to shut down the system after execution of their program.

11. The record book of the program performed in the immediate last session should be
submitted and certified by the staff member.
12. In the name of “LEARN EMERGING ADVANCES IN THE DOMAIN “(LEAD)
Experiments one or two tasks / experiments , beyond the University syllabus, are additionally
conducted in every laboratory.
LEAD EXPT: 1 will be conducted by faculty.
LEAD EXPT: 2 must be done by students on their interest (1 Experiment /1 Batch).
13. Students are instructed not to install any other software in the LAB systems
without permission of the in lab in charge
14. In case of any hardware/software problem, students are instructed inform to the
LAB faculty.

15. Shut down the system as soon as after finishing the work and keep the chairs in proper
order before leaving the lab.
PROGRAM EDUCATIONAL OBJECTIVES (PEO):

 To prepare graduates with a varied range of expertise in different aspects of data science
such as data collection, processing, modeling and visualization of large data sets.

 To acquire good knowledge of both theory and application of applied statistics,


mathematics and computer science based existing data science models to analyze huge
data sets originating from different application areas.

 To create models using the knowledge acquired from the program to solve future
challenges and real-world problems requiring large scale data analysis.

 To make better trained professionals to cater the growing demand for data scientists, data
analysts, data architects and data engineers in industry.
B.TECH II Year I Sem. LTPC
DS303PC: OPERATING SYSTEMS 0 02 1
(Common to CSE/IT/CSD/CSM/CSC)
Pre-requisites:
 A course on “Computer Programming and Data Structures”.
 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.
 Inter process 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 EXPERIMENT
1. Write C programs to simulate the following CPU Scheduling algorithms: -
a) FCFS (FIRST COME FIRST SERVE)
b) SJF (SHORTEST JOB FIRST)
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 a C program to simulate page replacement algorithms
a) FIFO (FIRST IN FIRST OUT)
b) LRU (LEAST RECENT USED)
c) OPR (Optimal Page Replacement)

LEAD EXPERIMENT

1. Write a C program to implement dinning philosopher problem using semaphore.

2. Write a program to implement contiguous memory allocation using First Fit


EXPERIMENT NO.1

1. Introduction of CPU scheduling algorithms –


a) FCFS,
b) SJF,
c) Round Robin,
d) Priority.

OBJECTIVE: The main objective is to understand clearly about all the process
scheduling algorithms.

PRE REQUISITES: Basic scheduling process technique and


communication techniques

DESCRIPTION:
1. Introduction to process techniques.
2. Introduction to scheduling techniques.
3. Implementation of scheduling algorithms.

APPLICATIONS:
1. These mechanisms can be practically applied in various Operating Systems.
2. These techniques are useful to improve the throughput.

PROGRAM:
a) FCFS
b) SJF
c) Round Robin
d) Priority

a) FCFS (FIRST COME FIRST SERVE) 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 p[10],at[10],bt[10],ct[10],tat[10],wt[10],i,j,temp=0,n;
float awt=0,atat=0;
printf("enter no of proccess you want:");
scanf("%d",&n);
printf("enter %d process:",n);
for(i=0;i<n;i++)
{
scanf("%d",&p[i]);
}
printf("enter %d arrival time:",n);
for(i=0;i<n;i++)
{
scanf("%d",&at[i]);
}
printf("enter %d burst time:",n);
for(i=0;i<n;i++)
{
scanf("%d",&bt[i]);
}
// sorting at,bt, and process according to at
for(i=0;i<n;i++)
{
for(j=0;j<(n-i);j++)
{
if(at[j]>at[j+1])
{
temp=p[j+1];
p[j+1]=p[j];
p[j]=temp;
temp=at[j+1];
at[j+1]=at[j];
at[j]=temp;
temp=bt[j+1];
bt[j+1]=bt[j];
bt[j]=temp;
}
}
}
/* calculating 1st ct */
ct[0]=at[0]+bt[0];
/* calculating 2 to n ct */
for(i=1;i<n;i++)
{
//when proess is ideal in between i and i+1
temp=0;
if(ct[i-1]<at[i])
{
temp=at[i]-ct[i-1];
}
ct[i]=ct[i-1]+bt[i]+temp;
}
/* calculating tat and wt */
printf("\np\t A.T\t B.T\t C.T\t TAT\t WT");
for(i=0;i<n;i++)
{
tat[i]=ct[i]-at[i];
wt[i]=tat[i]-bt[i];
atat+=tat[i];
awt+=wt[i];
}
atat=atat/n;
awt=awt/n;
for(i=0;i<n;i++)
{
printf("\nP%d\t %d\t %d\t %d \t %d \t %d",p[i],at[i],bt[i],ct[i],tat[i],wt[i]);
}
printf("\naverage turnaround time is %f",atat);
printf("\naverage wating timme is %f",awt);
return 0;
}
B) SJF (SHORTEST JOB 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:
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<string.h>
int main()
{
int bt[20],at[10],n,i,j,temp,st[10],ft[10],wt[10],ta[10];
int totwt=0,totta=0;
double awt,ata;
char pn[10][10],t[10];
//clrscr();
printf("Enter the number of process:");
scanf("%d",&n);
for(i=0; i<n; i++)
{
printf("Enter process name, arrival time& burst time:");
scanf("%s%d%d",pn[i],&at[i],&bt[i]);
}
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
if(bt[i]<bt[j])
{
temp=at[i];
at[i]=at[j];
at[j]=temp;
temp=bt[i];
bt[i]=bt[j];
bt[j]=temp;
strcpy(t,pn[i]);
strcpy(pn[i],pn[j]);
strcpy(pn[j],t);
}
}
for(i=0; i<n; i++)
{
if(i==0)
st[i]=at[i];
else
st[i]=ft[i-1];
wt[i]=st[i]-at[i];
ft[i]=st[i]+bt[i];
ta[i]=ft[i]-at[i];
totwt+=wt[i];
totta+=ta[i];
}
awt=(double)totwt/n;
ata=(double)totta/n;
printf("\nProcessname\tarrivaltime\tbursttime\twaitingtime\tturnaroundtime");
for(i=0; i<n; i++)
{
printf("\n%s\t%5d\t\t%5d\t\t%5d\t\t%5d",pn[i],at[i],bt[i],wt[i],ta[i]);
}
printf("\nAverage waiting time: %f",awt);
printf("\nAverage turnaroundtime: %f",ata);
return 0;
}
C) ROUND ROBIN:
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
8: Stop the process
Program:
#include <stdio.h>
#include<stdbool.h>
void queueUpdate(int queue[],int timer,int arrival[],int n, int maxProccessIndex)
{
int zeroIndex, i;
for( i = 0; i < n; i++)
{
if(queue[i] == 0)
{
zeroIndex = i;
break;
}
}
queue[zeroIndex] = maxProccessIndex + 1;
}
void queueMaintain(int queue[], int n)
{
int i;
for( i = 0; (i < n-1) && (queue[i+1] != 0) ; i++)
{
int temp = queue[i];
queue[i] = queue[i+1];
queue[i+1] = temp;
}
}

void checkNewArrival(int timer, int arrival[], int n, int maxProccessIndex,int queue[])


{
if(timer <= arrival[n-1])
{
bool newArrival = false;
int j;
for( j = (maxProccessIndex+1); j < n; j++)
{
if(arrival[j] <= timer){
if(maxProccessIndex < j){
maxProccessIndex = j;
newArrival = true;
}
}
}
//add incoming process to ready queue
if(newArrival)
queueUpdate(queue,timer,arrival,n, maxProccessIndex);
}
}
int main(){
int n,tq, timer = 0, maxProccessIndex = 0,i;
float avgWait = 0, avgTT = 0;
printf( "\n Time quantum : ");
scanf("%d",&tq);
printf( "\nNumber of processes : ");
scanf("%d",&n);
int arrival[n], burst[n], wait[n], turn[n], queue[n], temp_burst[n];
bool complete[n];
printf( "\nArrival time of the processes : ");
for(i = 0; i < n; i++)
scanf("%d",&arrival[i]);

printf("\nBurst time of the processes : ");


for( i = 0; i < n; i++)
{
scanf("%d",&burst[i]);
temp_burst[i] = burst[i];
}
for( i = 0; i < n; i++){
complete[i] = false;
queue[i] = 0;
}
while(timer < arrival[0])
timer++;
queue[0] = 1;

while(true){
bool flag = true;
for( i = 0; i < n; i++){
if(temp_burst[i] != 0){
flag = false;
break;
}
}
if(flag)
break;

for( i = 0; (i < n) && (queue[i] != 0); i++)


{
int ctr = 0;
while((ctr < tq) && (temp_burst[queue[0]-1] > 0))
{
temp_burst[queue[0]-1] -= 1;
timer += 1;
ctr++;

//Check & Update the ready queue until all processes arrive
checkNewArrival(timer, arrival, n,
maxProccessIndex, queue);
}
if((temp_burst[queue[0]-1] == 0) && (complete[queue[0]-1] == false)){
turn[queue[0]-1] = timer;
complete[queue[0]-1] = true;
}
//check if CPU is idle
bool idle = true;
if(queue[n-1] == 0){
for(int i = 0; i < n && queue[i] != 0; i++){
if(complete[queue[i]-1] == false){
idle = false;
}
}
}
else
idle = false;

if(idle)
{
timer++;
checkNewArrival(timer, arrival, n,
maxProccessIndex, queue);
}

//Maintain the entries of processes


queueMaintain(queue,n);
}
}

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


turn[i] = turn[i] - arrival[i];
wait[i] = turn[i] - burst[i];
}

printf("\nProcess No.\tArrival Time\tBurst Time\tWait Time\tTurnAround Time");

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


printf("%d %d %d %d",i+1, arrival[i],burst[i],wait[i],turn[i]);
}
for( i =0; i< n; i++){
avgWait += wait[i];
avgTT += turn[i];
}
printf("\nAverage wait time : %d Average Turn Around Time : %d ",(avgWait/n),
(avgTT/n));
return 0;
}
EXPERIMENT NO.2

2. Introduction of I/O System calls of UNIX/LINUX


OBJECTIVE: The main objective is to understand clearly about all the basic I/O
system calls in UNIX/LINUX.
PRE REQUISITES: Basic of system calls.
DESCRIPTION:
1. Introduction to I/O system calls.
2. Implementation of open, close, read, write, etc.
APPLICATIONS:
1. These mechanisms can be practically applied in various Operating Systems.
2. These techniques are useful to improve the throughput.
2. Write programs using the I/O system calls of UNIX/LINUX operating system (open,
read, write, close, fcntl, seek, stat, opendir, readdir)
a) 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:
HELLO
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:

WELCOME
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);

The ‘pathname’ argument is used for the name of the directory.

2. Opening directories

Syntax: DIR *opendir(const char *name);

3. Reading directories.

Syntax: struct dirent *readdir(DIR *dirp);

4. Removing directories.

Syntax: int rmdir(const char *pathname);

5. Closing the directory.

Syntax: int closedir(DIR *dirp);

6. 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 operations3. 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;
}
}
EXPERIMENT NO. 3
3. DEADLOCK AVOIDANCE OBJECTIVE: The main objective is to understand
clearly about Deadlocks technique.

PREREQUISITES:
Basic knowledge of Deadlock characteristics.

DESCRIPTION:
1. Introduction to Deadlocks.
2. Deadlock detection
3. Deadlock Avoidance
4. Data Recovery from Deadlocks.
5. Deadlock prevention.
APPLICATION:
1. It gives the correct idea of Deadlocks.
2. It helps the student to know about Deadlock detection, Deadlock avoidance &
prevention techniques.

a) AIM: -Write a C program to simulate the Bankers Algorithm for Deadlock


Avoidance.
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.
PROGRAM:
#include<stdio.h>
struct file
{
int all[10];
int max[10];
int need[10];
int flag;
};
void main()
{
struct file f[10];
int fl;
int i, j, k, p, b, n, r, g, cnt=0, id, newr;
int avail[10],seq[10];
clrscr();
printf("Enter number of processes -- ");
scanf("%d",&n);
printf("Enter number of resources -- ");
scanf("%d",&r);
for(i=0;i<n;i++)
{
printf("Enter details for P%d",i);

printf("\nEnter allocation\t -- \t");


for(j=0;j<r;j++)
scanf("%d",&f[i].all[j]);
printf("Enter Max\t\t -- \t");
for(j=0;j<r;j++)
scanf("%d",&f[i].max[j]);
f[i].flag=0;
}
printf("\nEnter Available Resources\t -- \t");
for(i=0;i<r;i++)
scanf("%d",&avail[i]);
printf("\nEnter New Request Details -- ");
printf("\nEnter pid \t -- \t");
scanf("%d",&id);
printf("Enter Request for Resources \t -- \t");
for(i=0;i<r;i++)
{
scanf("%d",&newr);
f[id].all[i] += newr;
avail[i]=avail[i] - newr;
}
for(i=0;i<n;i++)
{
for(j=0;j<r;j++)
{
f[i].need[j]=f[i].max[j]-f[i].all[j];
if(f[i].need[j]<0)
f[i].need[j]=0;
}
}
cnt=0;
fl=0;
while(cnt!=n) {
g=0;
for(j=0;j<n;j++) {
if(f[j].flag==0) {
b=0;
for(p=0;p<r;p++) {
if(avail[p]>=f[j].need[p])
b=b+1;
else
b=b
-1;
}
if(b==r) {
printf("
\nP%d is visited",j);
seq[fl++]=j;
f[j].flag=1;
for(k=0;k<r;k++)
avail[k]=avail[k]+f[j].all[k];
cnt=cnt+1;
printf("(");
for(k=0;k<r;k++)
printf("%3d",avail[k]);
printf(")");
g=1;
}
}
}
if(g==0)
{
printf("\n REQUEST NOT GRANTED -- DEADLOCK OCCURRED"); printf("\n
SYSTEM IS
IN UNSAFE STATE"); goto y;
}
}
printf("\nSYSTEM IS IN SAFE STATE");
printf("\nThe Safe Sequence is -- (");
for(i=0;i<fl;i++)
printf("P%d ",seq[i]);
printf(")");
y: printf("\nProcess\t\tAllocation\t\tMax\t\t\tNeed\n");
for(i=0;i<n;i++)
{
printf("P%d\t",i);
for(j=0;j<r;j++)
printf("%6d",f[i].all[j]);
for(j=0;j<r;j++)
printf("%6d",f[i].max[j]);
for(j=0;j<r;j++)
printf("%6d",f[i].need[j]);
printf("\n");
}
getch();
}
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. i.e. you cannot
request a resource whose no is less than any you may be holding.

6. Stop
PROGRAM:

#include< stdio.h>
#include< conio.h>
void 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!!");
getch();
}
EXPERIMENT NO.4

4. INTRODUCTION:-TO PRODUCER –CONSUMER PROBLEM USING


SEMAPHORES
OBJECTIVE:
The main objective is to understand clearly about IPC Mechanisms.
PRE REQUISITES:
Basic communication techniques
DESCRIPTION:
1. Introduction to communication techniques.
2. Implementation of inter process communication with pipes
3. Implementation of semaphores
APPLICATIONS:
1. These mechanisms can be practically applied in various Operating Systems.
2. These techniques are useful to improve the throughput.
3. These techniques are used to solve communication problems and Producer
– Consumer problem
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>
void main()
{
int buffer[10], bufsize, in, out, produce, consume, choice=0;
in = 0;
out = 0;
bufsize = 10;
while(choice !=3)
{
printf(“\n1. Produce \t 2. Consume \t3. Exit”);
printf(“\nEnter your choice: ”);
scanf(“%d”, &choice);

CMR Engineering College CSE-CSM

OS LAB 34

switch(choice){
case 1:if((in+1)%bufsize==out)
printf(“\nBuffer is Full”);
else
{
printf(“\nEnter the value: “);
scanf(“%d”, &produce);
buffer[in] = produce;
in = (in+1)%bufsize;
}
break;

case 2:if(in == out)


printf(“\nBuffer is Empty”);
else
{ consume = buffer[out];
printf(“\nThe consumed value is %d”, consume);
out = (out+1)%bufsize;
}
}
}

EXPERIMENT NO.5

5. INTRODUCTION TO PIPES, INTER-PROCESSOR COMMUNICATION


AND SEMAPHORES
OBJECTIVE:
The main objective is to understand clearly about IPC Mechanisms.
PRE REQUISITES:
Basic communication techniques
DESCRIPTION:
1.Introduction to communication techniques.
2.Implementation of inter process communication with pipes
3.Implementation of semaphores
APPLICATIONS:
1. These mechanisms can be practically applied in various Operating Systems.
2. These techniques are useful to improve the throughput.
3. These techniques are used to solve communication problems and Producer –
Consumer problem

AIM: Write C programs to illustrate the following IPC mechanisms

ALGORITHM:
1. Start the program.
2. Declare the variables.
3. Read the choice.
4. Create a piping processing using IPC.
5. Assign the variable lengths
6. “strcpy” the message lengths.
7. To join the operation using IPC .
8. Stop the program
a) PIPES
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MSG_LEN 64
int main(){
int result;
int fd[2];
char message[MSG_LEN];
char recvd_msg[MSG_LEN];
result = pipe (fd);
if (result < 0)
{
perror("pipe ");
exit(1);
}
strncpy(message,"Linux World!! ",MSG_LEN);
result=write(fd[1],message,strlen(message));
if (result < 0)
{
perror("write");
exit(2);
}
strncpy(message,"Understanding ",MSG_LEN);
result=write(fd[1],message,strlen(message));
if (result < 0)
{
perror("write");
exit(2);

}
strncpy(message,"Concepts of ",MSG_LEN);
result=write(fd[1],message,strlen(message));
if (result < 0)
{
perror("write");
exit(2);
}
strncpy(message,"Piping ", MSG_LEN);
result=write(fd[1],message,strlen(message));
if (result < 0)
{
perror("write");
exit(2);
}
result=read (fd[0],recvd_msg,MSG_LEN);
if (result < 0)
{
CMR Engineering College CSE-CSM

OS LAB 38

perror("read");
exit(3);
}
printf("%s\n",recvd_msg);
return 0;
}
b) Program: FIFOs
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#define FIFO_FILE "MYFIFO"
int main(void)
{
FILE *fp;
char readbuf[80];
/* Create the FIFO if it does not exist */ umask(0);
mknod(FIFO_FILE, S_IFIFO|0666, 0);
while(1)
{
fp = fopen(FIFO_FILE, "r"); fgets(readbuf, 80, fp);
printf("Received string: %s\n", readbuf); fclose(fp);
}
return(0);
}

#include <stdio.h>
#include <stdlib.h>
#define FIFO_FILE "MYFIFO"
int main(int argc, char *argv[])
{
FILE *fp;
if ( argc != 2 ) {
printf("USAGE: fifoclient [string]\n");
exit(1);
}
if((fp = fopen(FIFO_FILE, "w")) == NULL)
{
perror("fopen");
exit(1);
}
fputs(argv[1], fp);
fclose(fp);
return(0);
}

C) Message Queues

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
msg_type;
char
msg_text[1
00];
} 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(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) Shared Memory
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#define SEGSIZE 100
int main(int argc, char *argv[ ])
{
int shmid,cntr;
key_t key;
char *segptr;
char buff[]="poooda......";
key=ftok(".",'s');
if((shmid=shmget(key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666))== -1)

CMR Engineering College CSE-CSM

OS LAB 44

{
if((shmid=shmget(key,SEGSIZE,0))==-1)
{
perror("shmget");
exit(1);
}
}
else
{
printf("Creating a new shared memory seg \n");
printf("SHMID:%d",shmid);
}
system("ipcs –m");

if((segptr=(char*)shmat(shmid,0,0))==(char*)-1)
{
perror("shmat");
exit(1);
}
printf("Writing data to shared memory...\n");
strcpy(segptr,buff);
printf("DONE\n");
printf("Reading data from shared memory...\n");
printf("DATA:-%s\n",segptr);
printf("DONE\n");
printf("Removing shared memory Segment...\n");
if(shmctl(shmid,IPC_RMID,0)== -1)
printf("Can‟t Remove Shared memory Segment...\n");
else
printf("Removed Successfully");
}
EXPERIMENT NO. 6

6. Introduction to simulate the following memory management techniques


a) Paging
b) Segmentation
OBJECTIVE:
The main objective is to understand clearly about all the page replacement algorithms and
allocation techniques.
PRE REQUISITES:
Basic paging techniques.
DESCRIPTION:
1. Introduction to paging techniques.
2. Introduction to page replacement and allocation technique.
3. Implementation of page replacement algorithms.
APPLICATIONS:
1. These mechanisms can be practically applied in various secondary storage techniques
such as disk storage.
a) Paging
AIM: To write a C program to implement memory management using paging
technique.

ALGORITHM:
Step 1: Start the program.
Step 2: Read the base address, page size, number of pages and memory unit.
Step 3: If the memory limit is less than the base address display the memory limit
is less than limit.
Step 4: Create the page table with the number of pages and page address.
Step 5: Read the page number and displacement value.
Step 6: If the page number and displacement value is valid, add the displacement
value with the address corresponding to the page number and display the result.
Step 7: Display the page is not found or displacement should be less than page
size.
Step 8: Stop the program.
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();}
b) SEGMENTATION
AIM: To write a C program to implement memory management using segmentation
ALGORITHM:

Step 1: Start the program.


Step 2: Read the base address, number of segments, size of each segment, memory
limit.
Step 3: If memory address is less than the base address display “invalid memory
limit”.
Step 4: Create the segment table with the segment number and segment address
and display it.
Step 5: Read the segment number and displacement.
Step 6: If the segment number and displacement is valid compute the real address
and display the same.
Step 7: Stop the program.

PROGRAM:
#include<stdio.h>
#include<conio.h>
struct list
{
int seg;
int base;
int limit;
struct list *next;
} *p;
void insert(struct list *q,int base,int limit,int seg)
{
if(p==NULL)
{
p=malloc(sizeof(Struct list));

p->limit=limit;
p->base=base;
p->seg=seg;
p->next=NULL;
}
else
{
while(q->next!=NULL)
{
Q=q->next;
Printf(“yes”)
}
q->next=malloc(sizeof(Struct list));
q->next ->limit=limit;
q->next ->base=base;
q->next ->seg=seg;
q->next ->next=NULL;
}
}
int find(struct list *q,int seg)
{
while(q->seg!=seg)
{
q=q->next;
}
return q->limit;
}
int search(struct list *q,int seg)
{
while(q->seg!=seg)
{
q=q->next;
}
return q->base;
}
main()
{
p=NULL;
int seg,offset,limit,base,c,s,physical;
printf(“Enter segment table/n”);
printf(“Enter -1 as segment value for termination\n”);
do
{
printf(“Enter segment number”);
scanf(“%d”,&seg);

if(seg!=-1)
{
printf(“Enter base value:”);
scanf(“%d”,&base);
printf(“Enter value for limit:”);
scanf(“%d”,&limit);
insert(p,base,lmit,seg);
}
}
while(seg!=-1)
printf(“Enter offset:”);
scanf(“%d”,&offset);
printf(“Enter bsegmentation number:”);
scanf(“%d”,&seg);
c=find(p,seg);
s=search(p,seg);
if(offset<c)
{
physical=s+offset;
printf(“Address in physical memory %d\n”,physical);
}
else
{
printf(“error”);
}
}
7. Write C programs to simulate Page replacement policies

a) FCFS
b) LRU
c) Optimal
Page replacement Algorithm
A page replacement algorithm is a key component of virtual memory management in
operating systems. In systems with virtual memory, not all processes can be
accommodated in the physical memory (RAM) at the same time. Therefore, the operating
system needs to decide which pages to keep in the physical memory and which to swap out
to the disk when new pages need to be brought in.
The primary goal of a page replacement algorithm is to minimize the number of page faults
(instances where a requested page is not in the physical memory and must be loaded from
the disk). Different algorithms use various strategies to make this decision.
Page Fault:
Page faults are a normal and essential part of virtual memory systems. They allow the
operating system to efficiently manage memory by swapping pages in and out of the
physical memory as needed. However, excessive page faults can lead to degraded
performance, as fetching data from the disk is significantly slower compared to accessing
data from RAM. Efficient page replacement algorithms, such as those mentioned earlier
(like FIFO, LRU, etc.), help minimize the impact of page faults on system performance.
a) FCFS

DESCRIPTION:
The First In First Out (FIFO) Page Replacement Algorithm removes the Page in the frame
which is allotted long back. This means the useless page which is in the frame for a longer
time is removed and the new page which is in the ready queue and is ready to occupy the
frame is allowed by the First In First Out Page Replacement.
Algorithm:
1. Start the process
2. Declare the size of the memory
3. Get the number of pages to be inserted
4. Get the values of the pages
5. Declare a counter and a stack
6. For each page in the sequence:
a. If the page is not in memory:
i. If memory is not full:
- Load the page into memory
- Increment the counter
- Stack the page according to the counter value
ii. Else (Memory is full):
- Remove the least recently used page from the stack (the one at the bottom)
- Load the new page into the freed-up space
- Increment the counter
- Stack the new page according to the counter value
b. Else (Page is already in memory):
- Update relevant information (e.g., access time)
7. Display the values in the order they were stacked
8. Stop the process
Program:
#include < stdio.h >
int main()
{
int incomingStream[] = {4 , 1 , 2 , 4 , 5};
int pageFaults = 0;
int frames = 3;
int m, n, s, pages;
pages = sizeof(incomingStream)/sizeof(incomingStream[0]);
printf(" Incoming \ t Frame 1 \ t Frame 2 \ t Frame 3 ");
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(incomingStream[m] == temp[n])
{
s++;
pageFaults--;
}
}
pageFaults++;
if((pageFaults <= frames) && (s == 0))
{
temp[m] = incomingStream[m];
}
else if(s == 0)
{
temp[(pageFaults - 1) % frames] = incomingStream[m];
}
printf("\n");
printf("%d\t\t\t",incomingStream[m]);
for(n = 0; n < frames; n++)
{
if(temp[n] != -1)
printf(" %d\t\t\t", temp[n]);
else
printf(" - \t\t\t");
}
}
printf("\nTotal Page Faults:\t%d\n", pageFaults);
return 0;
}
b) LRU (Least Recently Used)
A) DESCRIPTION:
Least Recently Used (LRU) page replacement algorithm works on the concept that the
pages that are heavily used in previous instructions are likely to be used heavily in next
instructions. And the page that are used very less are likely to be used less in future.
Whenever a page fault occurs, the page that is least recently used is removed from the
memory frames. Page fault occurs when a referenced page in not found in the memory
frames.

PROGRAM FOR LRU PAGE REPLACEMENT ALGORITHM IN C

ALGORITHM:
1. Start the process
2. Declare the size
3. Get the number of pages to be inserted
4. Get the value
5. Declare counter and stack
6. Select the least recently used page by counter value
7. Stack them according the selection.
8. Display the values
9. Stop the process
PROGRAM:
#include<stdio.h>
#include<conio.h>
int fr[3];
void main()
{
void display();
int p[12]={2,3,2,1,5,2,4,5,3,2,5,2},i,j,fs[3];
int index,k,l,flag1=0,flag2=0,pf=0,frsize=3;
clrscr();
for(i=0;i<3;i++)
{
fr[i]=-1;
}
for(j=0;j<12;j++)
{
flag1=0,flag2=0;
for(i=0;i<3;i++)
{
if(fr[i]==p[j])
{
flag1=1;
flag2=1; break; }

}
if(flag1==0)
{
for(i=0;i<3;i++)
{
if(fr[i]==
-1)
{
fr[i]=p[j]; flag2=1;
break; }}
}
if(flag2==0)
{
for(i=0;i<3;i++)
fs[i]=0;
for(k=j-1,l=1;l<=frsize-1;l++,k--)
{
for(i=0;i<3;i++)
{
if(fr[i]==p[k]) fs[i]=1;
}}
for(i=0;i<3;i++)
{
if(fs[i]==0)
index=i;
}
fr[index]=p[j];
pf++;
}
display();
}
printf("\n no of page faults :%d",pf+frsize);
getch();
}
void display()
{
int i; printf("\n");
for(i=0;i<3;i++)
printf("\t%d",fr[i]);
}
c) Optimal
A) DESCRIPTION:
The Optimal Page Replacement algorithm, also known as the Belady's Optimal Page
Replacement algorithm, is an idealized page replacement algorithm that serves as a
benchmark for evaluating the performance of other page replacement algorithms. While it
is practically impossible to implement in real systems due to the need for future knowledge
of page accesses, it provides a theoretical upper bound on the performance of page
replacement strategies.
PROGRAM FOR OPTIMAL PAGE REPLACEMENT ALGORITHM IN C

ALGORITHM:
1. Start the process
2. Declare the size of the memory
3. Get the number of pages to be inserted
4. Get the values of the pages
5. Declare a counter and a stack
6. For each page in the sequence:
a. If the page is not in memory:
i. If memory is not full:
- Load the page into memory
- Increment the counter
- Stack the page according to the counter value
ii. Else (Memory is full):
- Find the page in memory that will not be used for the longest period
in the future (Optimal page)
- Remove the Optimal page from memory
- Load the new page into the freed-up space
- Increment the counter
- Stack the new page according to the counter value
b. Else (Page is already in memory):
- Update relevant information (e.g., access time)
7. Display the values in the order they were stacked
8. Stop the process

PROGRAM:
#include<stdio.h>
int main()
{
int n,pg[30],fr[10];
int count[10],i,j,k,fault,f,flag,temp,current,c,dist,max,m,cnt,p,x;
fault=0;
dist=0;
k=0;
printf("Enter the total no pages:\t");
scanf("%d",&n);
printf("Enter the sequence:");
for(i=0;i<n;i++)
scanf("%d",&pg[i]);
printf("\nEnter frame size:");
scanf("%d",&f);

for(i=0;i<f;i++)
{
count[i]=0;
fr[i]=-1;
}
for(i=0;i<n;i++)
{
flag=0;
temp=pg[i];
for(j=0;j<f;j++)
{
if(temp==fr[j])
{
flag=1;
break;
}
}
if((flag==0)&&(k<f))
{
fault++;
fr[k]=temp;
k++;
}
else if((flag==0)&&(k==f))
{
fault++;
for(cnt=0;cnt<f;cnt++)
{
current=fr[cnt];
for(c=i;c<n;c++)
{
if(current!=pg[c])
count[cnt]++;
else
break;
}
}
max=0;
for(m=0;m<f;m++)
{
if(count[m]>max)
{
max=count[m];
p=m;
}
}
fr[p]=temp;
}
printf("\npage %d frame\t",pg[i]);
for(x=0;x<f;x++)
{
printf("%d\t",fr[x]);
}
}
printf("\nTotal number of faults=%d",fault);
return 0;
}
LEAD EXPERIMENT

1. Write a program to implement dining philosopher problem using semaphore.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define NUM_PHILOSOPHERS 5

pthread_t philosophers[NUM_PHILOSOPHERS];
sem_t forks[NUM_PHILOSOPHERS];

void *philosopher(void *arg) {


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

while (1) {
printf("Philosopher %d is thinking.\n", philosopher_id);

// Wait for left fork


sem_wait(&forks[left_fork]);

// Wait for right fork


sem_wait(&forks[right_fork]);

// Eat
printf("Philosopher %d is eating.\n", philosopher_id);

// Release left and right forks


sem_post(&forks[left_fork]);
sem_post(&forks[right_fork]);

// Simulate some delay


usleep(rand() % 1000000);
}
}

int main() {
int i;
int philosopher_ids[NUM_PHILOSOPHERS];

// Initialize semaphores
for (i = 0; i < NUM_PHILOSOPHERS; ++i) {
sem_init(&forks[i], 0, 1);
}

// Create philosopher threads


for (i = 0; i < NUM_PHILOSOPHERS; ++i) {
philosopher_ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &philosopher_ids[i]);
}

// Join philosopher threads


for (i = 0; i < NUM_PHILOSOPHERS; ++i) {
pthread_join(philosophers[i], NULL);
}

// Destroy semaphores
for (i = 0; i < NUM_PHILOSOPHERS; ++i) {
sem_destroy(&forks[i]);
}

return 0;
}
2. Write a program to implement contiguous memory allocation using First Fit.

#include<stdio.h>
void main()
{
int bsize[10], psize[10], bno, pno, flags[10], allocation[10], i, j;
for(i = 0; i < 10; i++)
{
flags[i] = 0;
allocation[i] = -1;
}
printf("Enter no. of blocks: ");
scanf("%d", &bno);
printf("\nEnter size of each block: ");
for(i = 0; i < bno; i++)
scanf("%d", &bsize[i]);
printf("\nEnter no. of processes: ");
scanf("%d", &pno);
printf("\nEnter size of each process: ");
for(i = 0; i < pno; i++)
scanf("%d", &psize[i]);
for(i = 0; i < pno; i++) //allocation as per first fit
for(j = 0; j < bno; j++)
if(flags[j] == 0 && bsize[j] >= psize[i])
{
allocation[j] = i;
flags[j] = 1;
break;
}
//display allocation details
printf("\nBlock no.\tsize\t\tprocess no.\t\tsize");
for(i = 0; i < bno; i++)
{
printf("\n%d\t\t%d\t\t", i+1, bsize[i]);
if(flags[i] == 1)
printf("%d\t\t\t%d",allocation[i]+1,psize[allocation[i]]);
else
printf("Not allocated");
}
}

You might also like