0% found this document useful (0 votes)
17 views50 pages

Os Lab Record 21-22

Operating system

Uploaded by

Saketha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views50 pages

Os Lab Record 21-22

Operating system

Uploaded by

Saketha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

MATURI VENKATA SUBBA RAO ENGINEERING COLLEGE

(Affiliated to Osmania University & Recognized by AICTE)


Nadergul, Ranga Reddy Dist.

CERTIFICATE

Department of COMPUTER SCIENCE & ENGINEERING

Certified that this is a bonafide work of lab experiments carried out by


Mr/Ms. bearing Roll.No. under the course
of Operating Systems Laboratory prescribed by Osmania University for B.E. Sem-IV of
Computer Science & Engineering during the academic year 2021–2022.

Internal Examiner External Examiner


VISION AND MISSION

VISION

 To impart technical education of the highest standards, producing competent and confident engineers with an
ability to use computer science knowledge to solve societal problems.

MISSION

 To make learning process exciting, stimulating and interesting.


 To impart adequate fundamental knowledge and soft skills to students.
 To expose students to advanced computer technologies in order to excel in engineering practices by bringing
out the creativity in students.
 To develop economically feasible and socially acceptable software.

PROGRAM EDUCATIONAL OBJECTIVES (PEOs)

The Bachelor’s program in Computer Science and Engineering is aimed at preparing graduates who will:-
PEO-1: Achieve recognition through demonstration of technical competence for successful execution of software
projects to meet customer business objectives.
PEO-2: Practice life-long learning by pursuing professional certifications, higher education or research in the
emerging areas of information processing and intelligent systems at a global level.
PEO-3: Contribute to society by understanding the impact of computing using a multidisciplinary and ethical
approach.

(A) PROGRAM OUTCOMES (POs)

At the end of the program the students (Engineering Graduates) will be able to:
1. Engineering knowledge: Apply the knowledge of mathematics, science, engineering fundamentals, and an
engineering specialization to the solution of complex engineering problems.
2. Problem analysis: Identify, formulate, review research literature, and analyse complex engineering problems
reaching substantiated conclusions using first principles of mathematics, natural sciences, and engineering
sciences.
3. Design/development of solutions: Design solutions for complex engineering problems and design 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.
4. Conduct investigations of complex problems: Use research-based knowledge and research methods including
design of experiments, analysis and interpretation of data, and synthesis of the information to provide valid
conclusions.
5. Modern tool usage: Create, select, and apply appropriate techniques, resources, and modern engineering and IT
tools including prediction and modelling to complex engineering activities with an understanding of the
limitations.
6. The engineer and society: Apply reasoning informed by the contextual knowledge to assess societal, health,
safety, legal and cultural issues and the consequent responsibilities relevant to the professional engineering
practice.
7. Environment and sustainability: Understand the impact of the professional engineering solutions in societal and
environmental contexts, and demonstrate the knowledge of, and need for sustainable development.
8. Ethics: Apply ethical principles and commit to professional ethics and responsibilities and norms of the
engineering practice.
9. Individual and team work: Function effectively as an individual, and as a member or leader in diverse teams,
and in multidisciplinary settings.
10. Communication: Communicate effectively on complex engineering activities with the engineering 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.
11. Project management and finance: Demonstrate knowledge and understanding of the engineering and
management principle and apply these to one’s own work, as a member and leader in a team, to manage projects
and in multidisciplinary environments.
12. Lifelong learning: Recognize the need for, and have the preparation and ability to engage in independent and
life-long learning in the broadest context of technological change.

(B) PROGRAM SPECIFIC OUTCOMES (PSOs)

13. (PSO-1) Demonstrate competence to build effective solutions for computational real-world problems
using software and hardware across multi-disciplinary domains.
14. (PSO-2) Adapt to current computing trends for meeting the industrial and societal needs through a holistic
professional development leading to pioneering careers or entrepreneurship
Course Name: Operating Systems
Course Code: PC 452 CS
Academic Year:2021-22
Semester: IV

Course pre-requisites:
 Computer Organization/Architecture
 Programming in C/C++
 Data Structures

Course objectives:
 Learn different types of CPU scheduling algorithms.
 Demonstrate the usage of semaphores for solving synchronization problem.
 Understand memory management techniques and different types of
fragmentation that occur in them and various page replacement policies.
 Understand Banker‘s algorithm used for deadlock avoidance.
 Learn various disk scheduling Algorithms

Course outcomes:

Code No. Statement


Student will be able to
CO1 Describe the basic components of an operating system ,its structure and its
role in implementations for general purpose and real-time applications
CO2 Define the concepts of processes, threads and outline standard scheduling
algorithms for multi-tasking.
CO3 Discuss critical section problem and its use in concurrent programming,
including semaphore construction and handling of deadlocks.
CO4 Demonstrate the overview of system memory management.
CO5 Explain the implementations of file systems.
INDEX

Experiment Date of
S.No. Name of the Experiment Page
Date Submission
No.

Part – I (Shell Scripts)


1.1 Programs to demonstrate if conditions using shell scripts 2
1.2 Program to demonstrate cases using a shell script 5
1.3 Program to demonstrate loops using a shell script 7
Part – II (Processes)
2.1 Creating a new process & displaying process IDs 10
(orphanprocess)
2.2 Demonstration of parent waiting for a child process to end 11
2.3 Demonstration of zombie process 12
2.4 Demonstration of execl(); use of signal() 13
Part – III (Threads)
3.1 Creating a new thread (displaying common process ID) 14
3.2 Demonstration of main process waiting for threads to 16
complete
3.3 Sharing variables among threads 17
3.4 Single function handling multiple threads 18
Part – IV (CPU scheduling algorithms)
4.1 Simulation of FCFS CPU scheduling algorithm 19
4.2 Simulation of SJF CPU scheduling algorithm 21
4.3 Simulation of ROUND-ROBIN CPU scheduling algorithm 23
Part – V (IPC)
5.1 IPC using pipe 25
5.2 IPC using message queue 26
5.3 IPC using shared memory 28
Part – VI (Process synchronization)
6.1 Dining philosophers problem 30
6.2 Producer - consumer problem 33
6.3 Readers – writers problem 35
Part – VII(Deadlocks)
7.1 Banker's algorithm for Deadlock Avoidance 37
Part – VIII (Page replacement algorithms)
8.1 Simulation of FIFO page replacement algorithm 40
8.2 Simulation of LRU page replacement algorithm 42
Part – IX (Disk Scheduling algorithms)
9.1 Simulation of FCFS Disk Scheduling Algorithm 44
9.2 Simulation of SSTF Disk Scheduling Algorithm 45
Part – I (Shell Scripts)

SHELL

A Unix/Linux shell is a command-line interpreter that provides a traditional user interface for the
Unix/Linux operating system. Users direct the operation of the computer by entering commands as text
for a command line interpreter to execute, or by creating text scripts of one or more such commands.
Users typically interact with a Unix/Linux shell using a terminal emulator, however, direct operation via
serial hardware connections, or networking session, are common for server systems.

The most influential Unix/Linux shells have been the Bourne shell and the C shell. These shells
have both been used as the coding base and model for many derivative and work-alike shells with
extended feature sets.

The Bourne shell, "sh", was written by Stephen Bourne at AT&T as the original Unix command
line interpreter; it introduced the basic features common to all the Unix/Linux shells, including piping,
command substitution, variables, control structures for condition-testing and looping and filename wild-
carding.

SHELL SCRIPT

A shell script is a computer program (a set of shell commands) designed to be run by the Unix/Linux
shell, a command line interpreter. The various dialects of shell scripts are considered to be scripting
languages.

Typical operations performed by shell scripts include file manipulation, program execution, and printing
text.

In its most basic form, a shell script can provide a convenient variation of a system command where
special environment settings, command options, or post-processing apply automatically, but in a way
that allows the new script to still act as a fully normal Unix/Linux command.

1
1.1 Programs to demonstrate if conditions using shell scripting

AIM: To demonstrate various usage of If conditions using shell scripts

PROCESS:

The if...elif...fi statement is the one level advance form of control statement that allows Shell to make
correct decision out of several conditions.

Syntax-

if [ expression 1 ]
then
Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
Statement(s) to be executed if expression 3 is true
else
Statement(s) to be executed if no expression is true
fi

There is nothing special about this code. It is just a series of if statements, where each if is part of the
else clause of the previous statement. Here statement(s) are executed based on the true condition, if non
of the condition is true then else block is executed.

1.1.1 Program to find whether the given number is even or odd

clear
echo "shell script to find even or odd"
echo -n "enter a number = "
read a
if [ $((a%2)) -eq 0 ]
then
clear
echo "given number is even"
else
clear
echo "given number is odd"
fi
echo "press enter to continue.."
read a
clear

Output:

2
1.1.2 Program to find whether the given file name exists

clear
echo "shell script to find existance of file"
echo -n "enter a file name = "
read a
if [ ! -f $a ]
then
clear
echo "given file does not exist"
else
clear
echo "given file exists"
fi
echo "press enter to continue.."
read a
clear

Output:

3
1.1.3 Driving license validation

clear
echo "shell script for driving license validation"
echo -n "enter your age = "
read age
clear
if [ $age -lt 16 ]
then
echo "you are not eligible for driving license"
elif [ $age -eq 16 -o $age -eq 17 ]
then
echo "you are only eligible for lerners license"
elif [ $age -ge 18 ]
then
echo -n "do you have lerners license (yes=1/no=0)? "
read ll
clear
if [ $ll -eq 0 ]
then
echo "please apply lerners license first"
else
echo -n "how many days have passed since issue of lerners license = "
read lldays
clear
if [ $lldays -lt 30 ]
then
echo "please wait for more "$((30-lldays))"day(s) for applying permanent driving
license"
else
echo "you are eligible for appliying for permanent driving license"
fi
fi
fi
echo "please click enter to continue..."
read a
clear

Output:

4
1.2 Program to demonstrate cases using a shell script

AIM: To demonstrate how cases can be handled in the shell using a simple calculator application

PROCESS:

You can use multiple if...elif statements to perform a multiway branch. However, this is not always the
best solution, especially when all of the branches depend on the value of a single variable.

Unix/Linux Shell supports case...esac statement which handles exactly this situation, and it does so more
efficiently than repeated if...elif statements.

Syntax:

The basic syntax of the case...esac statement is to give an expression to evaluate and several different
statements to execute based on the value of the expression.

The interpreter checks each case against the value of the expression until a match is found. If nothing
matches, a default condition will be used.

case $choice in

pattern1)
Statement(s) to be executed if pattern1 matches
;;

pattern2)
Statement(s) to be executed if pattern2 matches
;;

*)
Statement(s) to be executed if pattern does not match any of above
;;

esac

Here the string word is compared against every pattern until a match is found. The statement(s)
following the matching pattern executes. If no matches are found, the case statement exits without
performing any action.

There is no maximum number of patterns, but the minimum is one.

When statement(s) part executes, the command ;; indicates that program flow should jump to the end of
the entire case statement. This is similar to break in the C programming language.

5
PROGRAM:

clear
echo "shell script for comman line calculator"
echo -n "enter a number = "
read a
echo -n "enter another number = "
read b
clear
echo "available operations -"
echo "1) Addition"
echo "2) Substraction"
echo "3) Multiplication"
echo "4) Division"
echo "please enter your choice from the above menu -"
read c
clear
case $c in
1) s="Addition = "$((a+b));;
2) s="Substracion = "$((a-b));;
3) s="Multipliation = "$((a*b));;
4) s="Division = "$((a/b));;
*) s="invalid option";;
esac
echo $s
echo "please click enter to continue..."
read a
clear

OUTPUT

6
1.3 Program to demonstrate iterations using a shell script

AIM: To demonstrate the concept of iterations considering while command for searching & sorting an
array in shell

PROCESS:

Loops are a powerful programming tool that enable you to execute a set of commands repeatedly.

While loop would execute given commands until given condition remains true where as until loop
would execute until a given condition becomes true.

Nesting Loops:

Nesting concept which means you can put one loop inside another similar or different loops. This
nesting can go upto unlimited number of times based on your requirement.

Nesting while Loops:

It is possible to use a while loop as part of the body of another while loop.

Syntax:

while [condition1] ------------------ this is loop1, the outer loop


do
Statement(s) to be executed if condition 1 is true

while [condition 2 ] ------------ this is loop2, the inner loop


do
Statement(s) to be executed if condition 2 is true
done

Statement(s) to be executed if command1 is true


done

7
1.3.1. Shell script to search a number in an array

clear
echo "shell script to search a number in a given array"
echo -n "enter array size = "
read n
echo "enter array values - "
i=1
while [ $i -le $n ]
do
read a[$i]
i=$((i+1))
done
clear
echo -n "enter a value to search in array = "
read v
clear
i=1
f="given value not found"
while [ $i -le $n ]
do
if [ $((a[i])) -eq $v ]
then
f="given value found at location "$i
fi
i=$((i+1))
done
echo $f
echo "please click enter to continue..."
read x
clear

OUTPUT:

8
1.3.2. Shell script to sort an array

clear
echo "shell script to sort a given array"
echo -n "enter array size = "
read n
echo "enter array values - "
i=1
while [ $i -le $n ]
do
read a[$i]
i=$((i+1))
done
clear
i=1
while [ $i -le $n ]
do
j=1
while [ $j -le $n ]
do
if [ $((a[i])) -lt $((a[j])) ]
then
temp=$((a[i]))
a[$i]=$((a[j]))
a[$j]=$temp
fi
j=$((j+1))
done
i=$((i+1))
done
echo "sorted array -"
i=1
while [ $i -le $n ]
do
echo $((a[i]))
i=$((i+1))
done
echo "please click enter to continue..."
read x
clear

OUTPUT

9
Part – II (Processes)

2.1 Creating a new process & displaying process IDs (orphan process)

AIM: To create a process and to display the process ID.

PROCESS :

Generally a process means any program under execution. First let us see the process id, the type
of process id is pid_t

If we want to know its process id in a c program we have the following function.pid_t getpid();

Each and every process will be associated with a parent process if want to know its id
pid_t getppid().

Fork() system call :

This fork system call will create a child process which is a copy of
parent process itself. But in parent process it (the fork system call)will return the id of the child (which
is >0)and in child process it will return 0,if it returns -1 child can not be created. All variables, data
structures will be inherited from parent to child.

PROGRAM:

#include<stdio.h>
#include<unistd.h>
main()
{
pid_t pid;
printf("\nhi i am parent process my pid=%d i am going to create a child\n",getpid());
pid=fork();
printf("\ncommon area-1 now accessed by pid=%d \n",getpid());
if(pid==0)
printf("\nhi i am child process my pid=%d my parents pid=%d \n",getpid(),getppid());
else if(pid>0)
printf("\nthis is parent's private area\n");
else if(pid<0)
printf("\nerror creating process\n");
else
printf("\nunknown error\n");
printf("\ncommon area-2 now accessed by pid=%d \n",getpid());
}

OUTPUT:

10
2.2 Demonstration of parent waiting for a child process to end

AIM : To Write a program to make a parent process wait for child process

PROCESS :

The child process turns orphan if the parent process terminates before the child process terminates
hence, we make use of the following functions -

sleep( ) usage: Sleep is used to make the currently running process to wait for the specific amount of
time that is given as arguments in the sleep function. The time will be in seconds.

wait() will be used to make parent to wait until child dies or completes its execution. If parent has
multiple child’s, we have to send one of the child id (for which parent has to wait, until this child
completes) as an argument to wait. Otherwise if parent has only one child pass NULL as an argument
to wait.

Syntax:
int wait (int *status);
int sleep(int time{in milliseconds});

PROGRAM:

#include<stdio.h>
#include<unistd.h>
main()
{
int signal;
pid_t pid;
printf("\nhi i am parent process my pid=%d i am going to create a child\n",getpid());
pid=fork();
if(pid==0)
{
sleep(5);
printf("\nhi i am child process my pid=%d my parents pid=%d \n",getpid(),getppid());
}
else if(pid>0)
{
printf("\nhi i am parent. i will wait for my child to complete\n");
wait(&signal); // Use sleep() to specify the waiting time and wait() to wait till the child
completes its process
printf("\ni got signal=%d so my child completed.i am exiting \n",signal);
}
else
printf("\nerror creating process\n");
}

OUTPUT:

11
2.3. Demonstration of zombie process

AIM : Write a program to create a zombie process

PROCESS :

A zombie process or defunct process is a process that has completed execution (via the exit system
call) but still has an entry in the process table: it is a process in the "Terminated state". This occurs for
child processes, where the entry is still needed to allow the parent process to read its child's exit status:
once the exit status is read via the wait system call, the zombie's entry is removed from the process table
and it is said to be "reaped". A child process always first becomes a zombie before being removed from
the resource table. In most cases, under normal system operation zombies are immediately waited on by
their parent and then reaped by the system – processes that stay zombies for a long time are generally an
errorand cause a resource leak.

The term zombie process derives from the common definition of zombie — an undead person. In the
term's metaphor, the child process has "died" but has not yet been "reaped". Also, unlike normal
processes, the kill command has no effect on a zombie process.

Zombie processes should not be confused with orphan processes: an orphan process is a process that is
still executing, but whose parent has died. These do not remain as zombie processes; instead, (like all
orphaned processes) they are adopted by init (process ID 1), which waits on its children. The result is
that a process that is both a zombie and an orphan will be reaped automatically.

PROGRAM :

#include<stdio.h>
#include<unistd.h>
main()
{
pid_t pid;
printf("\nhi i am parent process i am going to create a child\n");
pid=fork();
if(pid==0)
printf("\nhi i am child process. i have finished my job\n");
else if(pid>0)
{
printf("\nhi i am parent. i am going to pause\n");
pause();
}
else if(pid<0)
printf("\nerror creating process\n");
else
printf("\nunknown error\n");
}
OUTPUT:

12
2.4. Demonstration of execl(); use of signal()

AIM : Write a program to create a child process different from parent process

PROCESS :

execl is used to erase the current process with desired program. Generally in child process wewill use
execl() to execute desired program instead of executing copy of parent process

syntax: execl(char* path, char* program, char*arg1,char* arg2,… ...... NULL);

path: either absolute path or relative path from current directory of the program to beexecuted in
child(including program name also);(in string)
program: program name in string.

arg1,arg2: they will be passed as arguments to the new program going to be executed. Ending arg
must be NULL.

PROGRAM :

#include<stdio.h>
#include<unistd.h>
main()
{
int signal;
pid_t pid;
printf("\nhi i am parent process i am going to create a child\n");
pid=fork();
if(pid==0)
{
printf("\nhi i am child process. i am going to jump to a different parent process\n");
execl("/bin/ls","ls","-l",NULL);
}
else if(pid>0)
{
printf("\nhi i am parent. i will wait for my child to complete\n");
wait(&signal);
printf("\ni got signal=%d so my child jumped to another process.i am exiting \n",signal);
}
else if(pid<0)
printf("\nerror creating process\n");
else
printf("\nunknown error\n");
}

OUTPUT:

13
Part – III (Threads)

3.1 Creating a new thread (displaying common process ID)

AIM : Write a program to illustrate creation of thread using POSIX threads

PROCESS :

Threads:

Def: We can define a thread as a flow of execution in our program, (generally what is meant by flow
of execution is execution of a sample of code sequentially instruction by instruction for example main
also a flow of execution(thread), which execute one statement after one sequentially)

Now imagine a multi-threading concept that means parallel to the flow of execution of main,
there are some more flows of execution in our program. These flows of execution are called
THREADS and these flows of executions, they will be executed in parallel. Hence, we cannot expect
the order of output in our multi-threading concept. Just, these multi-threading concept will be useful
when we require a situation like, while main is executing, we have to do some more task in background
without knowledge of main.

A process may be a single threaded process (main thread) or it may be a multi- threaded
process. That means each and every thread will be associated with a process and a process may consists
of multiple threads. Those multiple threads belonging to single process can share the data, files of that
process, but each and every thread will be associated with its own stack and probably general purpose
registers as shown below.

int pthread_create(pthread_t* thread,pthread_attr_t* attr, fun-name, void* msg);

Purpose : To create new thread

Arguments

First : we have to pass a pointer to a variable of type pthread_t ,in which compiler will put theid of
newly created thread.

Second : It corresponds to thread attributes we will pass a NULL here.

Third : each thread will be associated with a piece of code, here it will be in the form offunction
whose return type is void* and parameter also void*

Fourth : It is a void pointer which will be passed to thread function.

14
PROGRAM:

#include<stdio.h>
#include<pthread.h>
void* hi()
{
printf("Hi I am a thread. My ID is: %d",getpid());
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,hi,NULL);
printf("\n I am main process. My ID is: %d \n", getpid());
}

OUTPUT:

15
3.2 Demonstration of main process waiting for threads to complete

AIM:To make the main process to wait for the child process to complete.

PROCESS :

Function-1:
int pthread_join (pthread_t th, void** return);

Purpose : to make parent thread to wait until child thread completes its execution.

Arguments

First : A parent thread ( generally main thread) will have so many child threads, we have to mention for
which child, parent has to wait,for that we will pass the thread id of the child for which parent has to
wait.
Second : Since we are waiting at join function call statement , that function will return a value here, we
will catch it in a variable of type void*, and we have to pass address of this void* variable as an
argument.

Function-2: [ if required ]
int pthread_exit(void* ret);

Purpose: This will be used in thread function to return a value to join statement of main thread.
parameter is return value which is a void pointer to return value.

PROGRAM:
#include<stdio.h>
#include<pthread.h>
void* hi()
{
int a;
printf("\n I am a thread. \n");
printf("\n Enter a value.\n");
scanf("%d",&a);
printf("a= %d",a);
}
int main()
{
pthread_t tid;
printf("\n I am main process.\n");
pthread_create(&tid,NULL,hi,NULL);
pthread_join(tid,NULL); //sleep() partially work & wait() does not work
printf("\nI came back to the main process.\n");
}

OUTPUT:

16
3.3 Sharing variables among threads and the main process (many to many)

AIM : To illustrate sharing of variables between threads and main process

PROCESS :

Few variables are declared in the global scope are shared and simultaneously accessed by the threads
created by the main process.

This is to prove that the threads created by a main process share the resources of that process unlike the
child process which runs in own instance scope.

PROGRAM:

#include<stdio.h>
#include<pthread.h>
int a,b;
void* add()
{
printf("Sum of two numbers = %d\n",a+b);
}
void* sub()
{
printf("Difference of two numbers = %d\n",a-b);
}
int main()
{
printf("enter a,b");
scanf("%d%d",&a,&b);
pthread_t tid1,tid2;
printf("\n I am the main process");
pthread_create(&tid1,NULL,add,NULL);
pthread_create(&tid2,NULL,sub,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("\n Back to main process \n");
}

OUTPUT:

17
3.4 Single function handling multiple threads

AIM : To illustrate how a single function can handle more than one threads

PROCESS :

We make use of two functions here,

pthread_self - obtain ID of the calling thread


The pthread_self() function returns the ID of the calling thread.
pthread_t pthread_self(void);

pthread_equal - compare thread Ids


This function shall compare the thread IDs t1 and t2.
The pthread_equal() function shall return a non-zero value if t1 and t2 are equal; otherwise,
zero shall be returned.
If either t1 or t2 are not valid thread IDs, the behavior is undefined.
int pthread_equal(pthread_t t1, pthread_t t2);

PROGRAM:

#include<pthread.h>
#include<stdio.h>
int a,b;
pthread_t tid[2];
void* f()
{
pthread_t id=pthread_self();
if(pthread_equal(id,tid[0]))
printf("Sum:%d\n",(a+b));
if(pthread_equal(id,tid[1]))
printf("Difference:%d\n",(a-b));
}
void main()
{
pthread_t tid1,tid2;
int i;
printf("\nMain Thread");
printf("\nEnter 2 numbers");
scanf("%d%d",&a,&b);
for(i=0;i<2;i++)
pthread_create(&tid[i],NULL,f,NULL);
for(i=0;i<2;i++)
pthread_join(tid[i],NULL);
printf("The first number is: %d",a);
}

OUTPUT:

18
Part – IV (CPU scheduling algorithms)

4.1 Simulation of FCFS CPU scheduling algorithm

AIM: To schedule the given processes using the FCFS algorithm.

PROCESS:

In this algorithm the process which comes first will be processed first .After giving the number of
processes and their burst time and arrival time we will get total waiting time by calculating sum of the
difference of individual process burst time and arrival time.Total waiting time by number of processes
gives the average waiting time of all the processes.

Sum of burst time and waiting of the particular process gives the turnaround time of that process. Sum
of all the turnaround times gives the total turnaround time of all the processes.
Total turnaround time by number of processes gives the Average turnaround time of all the processes.

PROGRAM:

#include<stdio.h>
void display();
void getdata ();
void wait();
void turnaround();
int i,n,at[10],bt[10],wt[10],tat[10];
float twt=0,ttat=0;
void main()
{
system("clear");
printf("\n***** FCFS ( FIRST COME FIRST SERVE ) SCHEDULING ******\n");
getdata();
wait();
turnaround();
display();
}
void getdata()
{
printf("\nEnter the number of process - ");
scanf("%d",&n);
for(i=0; i<n; i++)
{
printf("\nEnter the %d process burst time & arrival time : ",i+1);
scanf("%d %d",&bt[i],&at[i]);
}
}
void wait()

19
{
int s=0;
wt[0]=0;
for(i=1; i<n; i++)
{
s=s+bt[i-1];
wt[i]=s-at[i];
twt=wt[i]+twt;
}
}
void turnaround()
{
tat[-1]=0;
for(i=0; i<n; i++)
{
tat[i]=bt[i]+wt[i];
ttat=ttat+tat[i];
}
}
void display()
{
printf("\nPROCESS\t|BURST TIME\t|ARRIVAL TIME\t|WAIT TIME\t|TURN AROUND
TIME\n");
for(i=0; i<n; i++)
{
printf("%d\t|%d\t\t|%d\t\t|%d\t\t|%d\n",i+1,bt[i],at[i],wt[i],tat[i]);
}
printf("\nTotal Waiting time (TWT) = %f",twt);
printf("\nAverage Waiting time (AWT) = %f",twt/n);
printf("\n\nTotal Turn Around Time(TAT) = %f",ttat);
printf("\nAverage Turn Around Time Avg.(TAT) = %f \n\n",ttat/n);
}

OUTPUT:

20
4.2 Simulation of SJF CPU scheduling algorithm (non pre-emptive)

AIM:To schedule the given processes using SJF algorithm.

PROCESS:

This algorithm associates with each process the length of the process's next CPU burst. When the CPU
is available, it is assigned to the process that has the smallest next CPU burst. If the next CPU bursts of
two processes are the same, FCFS scheduling is used.

PROGRAM:

#include<stdio.h>
main()
{
system("clear");
int time,bt[10],at[10],sum_bt=0,small,n,i;
int sum_turnaround=0,sum_wait=0;
printf("***** SJF ( SHORTEST JOB FIRST ) NON-PRE-EMPTIVE SCHEDULING
******\n\n");
printf("Enter no of processes : ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter arrival time & burst time for process %d : ",i+1);
scanf("%d%d",&at[i],&bt[i]);
sum_bt+=bt[i];
}
bt[9]=9999;
printf("\n\nProcess\t|Arrival Time\t|Burst Time\t|Waiting Time\t|Turn Around Time\n");
for(time=0;time<sum_bt;)
{
small=9;
for(i=0;i<n;i++)
{
if(at[i]<=time && bt[i]>0 && bt[i]<bt[small])
small=i;
}
if(small==9)
{
time++;
continue;
}
printf("%d\t|%d\t\t|%d\t\t|%d\t\t|%d\t\n",small+1,at[small],bt[small],time-
at[small],time+bt[small]-at[small]);
sum_turnaround+=time+bt[small]-at[small];

21
sum_wait+=time-at[small];
time+=bt[small];
bt[small]=0;
}
printf("\nTotal Waiting Time (TWT) = %f",sum_wait*1.0);
printf("\nAverage Waiting Time (AWT) = %f",sum_wait*1.0/n);
printf("\n\nTotal Turn Around Time(TAT) = %f",sum_turnaround*1.0);
printf("\nAverage Turnaround Time (ATAT) = %f \n\n\n",sum_turnaround*1.0/n);
}

OUTPUT:

22
4.3 Simulation of ROUND-ROBIN CPU scheduling algorithm

AIM : Write C program showing the Round Robin Scheduling Algorithm.

PROCESS:

Round robin scheduling is a preemptive version of first-come, first-served scheduling. Processes are
dispatched in a first-in-first-out sequence but each process is allowed to run for only a limited amount
of time. This time interval is known as a time-slice or quantum. If a process does not complete or get
blocked because of an I/O operation within the time slice, the time slice expires and the process is
preempted. Process gets blocked because of an I/O operation), it is then preempted. This preempted
process is placed at the back of the run queue where it must wait for the processes that were already on
the list to cycle through the CPU.

PROGRAM:

#include<stdio.h>
void main()
{
int n,i,q,x=0,count=0,temp;
int bt[10],temp_bt[10],tat[10],wt[10];
float twt=0,ttat=0;
system("clear");
printf("***** RR (ROUND ROBIN) SCHEDULING ******\n");
printf("\nEnter the number of processes : ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter the burst time of process %d : ",i);
scanf("%d",&bt[i]);
temp_bt[i]=bt[i];
}
printf("\nEnter the time quantum : ");
scanf("%d",&q);
while(1)
{
for(i=0;i<n;i++)
{
temp=q;
if(temp_bt[i]==0)
{
count++;
continue;
}
if(temp_bt[i]>q)
temp_bt[i]=temp_bt[i]-q;

23
else if(temp_bt[i]>=0)
{
temp=temp_bt[i];
temp_bt[i]=0;
}
x=x+temp;
tat[i]=x;
}
if(n==count)
break;
}
for(i=0;i<n;i++)
{
wt[i]=tat[i]-bt[i];
twt=twt+wt[i];
ttat=ttat+tat[i];
}
printf("\nProcess\t|Burst Time\t|Wait Time\t|Turn-Around Time");
for(i=0;i<n;i++)
{
printf("\n%d\t|%d\t\t|%d\t\t|%d",i,bt[i],wt[i],tat[i]);
}
printf("\n\nTotal waiting time is %f",twt);
printf("\nAverage waiting time is %f",twt/n);
printf("\n\nTotal turn around time is %f",ttat);
printf("\nAverage turn around time is %f\n\n",ttat/n);
}

OUTPUT:

24
Part – V (IPC)

5.1 IPC using pipe

AIM : Write a program to illustrate IPC using "pipe" system call

PROCESS;

pipe concept is used to pass messages from parent to child process and vice-versa.

Functions : pipe(), write() and read().


int pipe(int fd[2]);

Purpose: It uses pipe system call to pass messages from parent to child process and vice versa. Here
descriptors in fd[0], fd[1] will be used to read from and write into the pipe using read and write
methods.

PROGRAM:
#include<stdio.h>
int main()
{
int pip[2];
pipe(pip[2]);
char s[10];
int p=fork();
if(p>0)
{
printf("parent process, sending msg to child");
write(pip[1],"Hello child",12);
wait();
read(pip[0],s,11);
printf("\n Received msg from child: =%s\n",s);
}
if(p==0)
{
printf("Hi, this is child.");
read(pip[0],s,12);
printf("\n Recieved msg from parent=%s\n",s);
write(pip[1],"Hello parent",12);
}
}
OUTPUT:

25
5.2 IPC using message queue

AIM : Write a program to illustrate two independent process communicate


using Message Queues.

PROCESS :

Message queues is also one of the IPC technique, in which we send messages from one process to
other process in the form of blocks (structures in c).Just like in shared memory, first we have to
get the msgqueue id using the key of the msgqueue and then we can either send a message to a process
or receive a message from other process.

Functions are also so similar to shared memories.


First Function :
5.2.1 int msgget(key_t key,int msgflag);
First argument is the KEY of the msg queue.
The msgflag is two types
5.2.1.1 IPC_CREAT| 0666,if we have to create the msg queue for the first time.
5.2.1.2 0666, if we have to just get the key of the msg queue which has been already created by any
other process.
Second Function :
5.2.2 int msgsnd(int mid,sturct buf* ptr,int length,int flag);
mid => id returned by msgget() function;
Second argument expects the address or pointer to the message which is to be sent to other process by
msg queue.
Third argument is the length of the message.
Generally flag will be send as 0.
Third Function :
5.2.3 int msgrcv(int mid,sturct buf* ptr,int length,long msgtype,int flag);
mid => id returned by msgget() function;
Second argument expects the address or pointer to the buffer where it has to put the messagesent by
other process via msg queue.
Third argument is the length of the message.
Fourth argument generally we will put msg type to 0 th type
Generally flag will be send as 0.

PROGRAM:

//program to send message

#include<stdio.h>
#include<sys/msg.h>
#include<sys/ipc.h>
struct msgbuf
{
long mtype;
char mtext[20];
};

26
int main()
{
struct msgbuf m;
int msgid=msgget(124,IPC_CREAT|0666);
m.mtype=1;
printf("Enter a msg");
scanf("%s",&m.mtext);
msgsnd(msgid,&m,20,0);
}

OUTPUT:

// program to receive message

#include<stdio.h>
#include<sys/msg.h>
#include<sys/ipc.h>
struct msgbuf
{
long mtype;
char mtext[20];
};
int main()
{
struct msgbuf m;
int msgid=msgget(124,IPC_CREAT|0666);
m.mtype=1;
msgrcv(msgid,&m,20,1,0);
printf(" The msg is : %s,\n %d",m.mtext,msgid);
}

OUTPUT:

27
5.3 IPC using shared memory

AIM : Write a program to illustrate communication between processes using shared


memory.

PROCESS :

Shared memory (shm) is also one of IPC (inter process communication) technique like pipes, but
pipes are use full to communicate parent and child process.

But here shared memory concept is supporting communication between any two independent processes.
Generally every shared memory is associated with a key. if process knows the key of that shared
memory, then it can attach to that shared memory and it will return a pointer to that shared memory and
we can read or write in to that shared memory using that pointer .

First Function:
int shmget(key_t key, size_t size, int flag);

First argument is the KEY of the shared memory. Second argument is SIZE of the shared memory. The
flag is two types

IPC_CREAT| 0666,if we have to create the shared memory for the first time.

0666, if we have to just get the key of the shared memory which has been already created by any
other process.
if return value is > 0, success and return value = id of desired shm = -1, failure and we cannot create
shm with that key (already another shm is created with that key) or we can not get the id of desired shm.

Second Function:

char* shmat(int shmid,char* shmaddr, int flag);

shmid is the return value of the shmget() function, here we have to pass it as first argument.

Generally shmaddr will be passed as NULL, and flag = 0.

Return value is pointer to desired shared memory segment. Thus we can read or write in to that
shared memory.

28
PROGRAM:

//program to write data at the shared memory location

#include<stdio.h>
#include<sys/shm.h>
#include<sys/ipc.h>
int main()
{
char *s;
int shmid=shmget(1234,20,IPC_CREAT|0666);
s=shmat(shmid,NULL,0);
printf("Enter a msg: \n");
scanf("%s",s);
}

OUTPUT:

//program to read data from the shared memory location


#include<stdio.h>
#include<sys/shm.h>
#include<sys/ipc.h>
int main()
{
char *s;
int shmid=shmget(1234,20,IPC_CREAT|0666);
s=shmat(shmid,NULL,0);
printf("Entered msg: %s \n",s);
}
OUTPUT:

29
Part – VI (Process synchronization)

6.1. Dining philosophers problem

AIM: To demonstrate a solution for Dining Philosophers problem.

PROCESS:

Problem

The dining philosophers problem is invented by E. W. Dijkstra. Imagine that five philosophers who
spend their lives just thinking and eating. In the middle of the dining room is a circular table with five
chairs. The table has a big plate of spaghetti. However, there are only five chopsticks available, as
shown in the following figure-

Each philosopher thinks. When he gets hungry, he sits down and


picks up the two chopsticks that are closest to him. If a
philosopher can pick up both chopsticks, he eats for a while.
After a philosopher finishes eating, he puts down the chopsticks
and starts to think.

Analysis
First, we notice that these philosophers are in a thinking-picking up chopsticks-eating-putting down
chopsticks cycle as shown below-

The "pick up chopsticks" part is the key point. The problem is each chopstick is shared by two
philosophers and hence a shared resource. We certainly do not want a philosopher to pick up a
chopstick that has already been picked up by his neighbor. This is a race condition. To address this
problem, we may consider each chopstick as a shared item protected by a mutex lock. Each
philosopher, before he can eat, locks his left chopstick and locks his right chopstick. If the acquisitions
of both locks are successful, this philosopher now owns two locks (hence two chopsticks), and can eat.
After finishes eating, this philosopher releases both chopsticks, and thinks! This execution flow is
shown below-

30
Because we need to lock and unlock a
chopstick, each chopstick is
associated with a mutex lock. Since
we have five philosophers who think
and eat simultaneously, we need to
create five threads, one for each
philosopher. Since each philosopher
must have access to the two mutex
locks that are associated with its left
and right chopsticks, these mutex
locks are global variables.

Thus, each Philosopher is represented by the following pseudocode:

process P[i]
while true do
{ THINK;
PICKUP(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]);
EAT;
PUTDOWN(CHOPSTICK[i], CHOPSTICK[i+1 mod 5])
}

PROGRAM:
#include<semaphore.h>
#include<stdio.h>
#include<pthread.h>
sem_t chopstick[5];
pthread_t philosopher[5];
void* runner(void* arg)
{
int i=*(int*)arg;
printf("Philosopher %d is thinking \n",i);
sleep(2);
sem_wait(&chopstick[i]);

31
sem_wait(&chopstick[(i+1)%5]);
printf("philosopher %d is eating \n",i);
sleep(3);
sem_post(&chopstick[i]);
sem_post(&chopstick[(i+1)%5]);
printf("Philosopher %d finished eating \n",i);
}
int main()
{
int i;

for(i=0;i<5;i++)
sem_init(&chopstick[i],0,1);

for(i=0;i<5;i++)
{
pthread_create(&philosopher[i],NULL,runner,&i);
sleep(1);
}

for(i=0;i<5;i++)
pthread_join(philosopher[i],NULL);
}

OUTPUT:

32
6.2. Producer - consumer problem

AIM: To demonstrate a solution for producer consumer problem.

PROCESS:

Problem

In computing, the producer–consumer problem (also known as the bounded-buffer problem) is a


classic example of a multi-process synchronization problem. The problem describes two processes, the
producer and the consumer, who share a common, fixed-sizebuffer used as a queue. The producer's job
is to generate a piece of data, put it into the buffer and start again. At the same time, the consumer is
consuming the data (i.e., removing it from the buffer) one piece at a time. The problem is to make sure
that the producer won't try to add data into the buffer if it's full and that the consumer won't try to
remove data from an empty buffer.

Analysis

The solution for the producer is to either go to sleep or discard data if the buffer is full. The next time
the consumer removes an item from the buffer, it notifies the producer, who starts to fill the buffer
again. In the same way, the consumer can go to sleep if it finds the buffer to be empty. The next time
the producer puts data into the buffer, it wakes up the sleeping consumer. The solution can be reached
by means of inter-process communication, typically using semaphores. An inadequate solution could
result in a deadlock where both processes are waiting to be awakened. The problem can also be
generalized to have multiple producers and consumers.

33
PROGRAM:

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
sem_t b,empty,full; //pthread_mutex_t mutex;
int buf=0;
void * prod()
{
while(1)
{
sem_wait(&empty);
sem_wait(&b); //pthread_mutex_lock(&mutex);
buf++;
printf("Produced buf = %d\n",buf);
sleep(1);
sem_post(&b); //pthread_mutex_unlock(&mutex);
sem_post(&full);
if(buf==5)
sleep(60);
}
}
void * cons()
{
while(1)
{
sleep(5);
sem_wait(&full);
sem_wait(&b); //pthread_mutex_lock(&mutex);
buf--;
printf("Consumed buf = %d\n",buf);
sleep(1);
sem_post(&b); //pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
}
void main()
{
pthread_t p,c;
sem_init(&empty,0,5);
sem_init(&full,-5,0);
sem_init(&b,0,1); //line to be removed when mutex is used along with semaphore
pthread_create(&p,NULL,prod,NULL);
pthread_create(&c,NULL,cons,NULL);
pthread_join(p,NULL);
pthread_join(c,NULL);
}
OUTPUT:

34
6.3. Readers – writers problem

AIM: To demonstrate a solution for the Readers-Writers problem.

PROCESS:

Problem

There is a data area shared among a number of processes. The data area could be a file, a block of
main memory, or even a bank of processor registers. There are number of processes that only read the
data area(readers) and a number that only write to the data area(writers). The conditions that must be
satisfied are as follows:
1. Any number of readers may simultaneously read the file.
2. Only one writer at a time may write to the file.
3. If a writer is writing to the file, no reader may read it.

Analysis

In the solution, the semaphores mutex and writeblock are initialized to 1 and rcount is initialized to 0.
Mutex and wrt are both common to reader and writer process. Mutex semaphore is used to ensure
mutual-exclusion when the variable rcount is updated.
Rcount keeps track of how many processes are currently reading the object.
Wrt functions as a mutual-exclusion semaphore for the writers. It is also used by the first or last reader
that enters or exits the critical section but not by the readers who enter or exit the critical section while
other readers are in their critical section.

PROGRAM:

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
sem_t b; //pthread_mutex_t mutex;
sem_t r;
int buf=0,i,rcount=0;

void * reader()
{
while(1)
{
sleep(5);
sem_wait(&r);
rcount++;
if(rcount==1)
sem_wait(&b); //pthread_mutex_lock(&mutex);
printf("a reader reads buf data = %d\n",buf);
sleep(5);
sem_post(&r);

35
rcount--;
if(rcount==0)
sem_post(&b); //pthread_mutex_unlock(&mutex);
}
}

void * writer()
{
while(1)
{
sleep(2);
sem_wait(&b); //pthread_mutex_lock(&mutex);
buf++;
printf("Data writen by the writer buf data = %d\n",buf);
sleep(2);
sem_post(&b); //pthread_mutex_lock(&mutex);
}
}

int main()
{
pthread_t rtid[5],wtid[5];
sem_init(&b,0,1); //remove this while using mutex
sem_init(&r,0,5);
for(i=0;i<5;i++)
{
pthread_create(&wtid[i],NULL,writer,NULL);
pthread_create(&rtid[i],NULL,reader,NULL);
}
for(i=0;i<5;i++)
{
pthread_join(wtid[i],NULL);
pthread_join(rtid[i],NULL);
}
}

OUTPUT:

36
PART – VII (DEADLOCKS)

7.1 Bankers algorithm (Deadlock Avoidance)

AIM : Write C program showing the Banker's algorithm.

PROCESS:

The Banker's algorithm is a resource allocation and deadlock avoidance algorithm developed by Edsger
Dijkstra that tests for safety by simulating the allocation of predetermined maximum possible amounts of
allresources, and then makes an "s-state" check to test for possible deadlock conditions for all other
pending activities, before deciding whether allocation should be allowed to continue.

For the Banker's algorithm to work, it needs to know three things:


 How much of each resource each process could possibly request[MAX]
 How much of each resource each process is currently holding[ALLOCATED]
 How much of each resource the system currently has available[AVAILABLE]
Resources may be allocated to a process only if it satisfies the following conditions:
1.request ≤ max, else set error condition as process has crossed maximum claim made by it.
2.request ≤ available, else process waits until resources are available.

PROGRAM:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h> #define true 1 #define false 0
int m,n,i,j,count=0,process;
int max[10][10],alloc[10][10],need[10][10],c[10],avail[10],finish[10];
void readtable(int t[10][10])
{
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&t[i][j]);
}
void printtable(int t[10][10])
{
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
printf("\t%d",t[i][j]);
printf("\n");
}
}
void readvector(int v[10])
{
for(j=0;j<n;j++)
scanf("%d",&v[j]);
}

37
void printvector(int v[10])
{
for(j=0;j<n;j++)
printf("\t%d",v[j]);
}
void init()
{
printf("enter the number of process\n");
scanf("%d",&m);
printf("enter the number of resources\n");
scanf("%d",&n);
printf("enter the claim table\n");
readtable(max);
printf("enter the allocation table\n");
readtable(alloc);
printf("enter the max units of each resource\n");
readvector(c);
for(i=0;i<n;i++)
finish[i]=false;
}
void findavail()
{
int sum; for(j=0;j<n;j++)
{
sum=0;
for(i=0;i<m;i++)
{
sum=sum+alloc[i][j];
}
avail[j]=c[j]-sum;
}
}
void findneed()
{
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
need[i][j]=max[i][j]-alloc[i][j];
}
}
}
void selectprocess()
{
int flag; for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(need[i][j]<=avail[j])

38
flag=1; else
{
flag=0;
break;
}
}
if((flag==1)&&(finish[i]==false))
{
process=i;
count++;
break;
}
}
printf("current status is\n"); printtable(alloc); if(flag==0)
{
printf("system is in unsafe state\n"); exit(1);
}
printf("system is in safe state");
}
void executeprocess(int p)
{
printf("excuting process is %d",p); printtable(alloc);
}
void releaseresource()
{
for(j=0;j<n;j++)
avail[j]=avail[j]+alloc[process][j];
for(j=0;j<n;j++)
{
alloc[process][j]=0;
need[process][j]=0;
}
}
int main()
{
init();
findavail();
findneed();
do{
selectprocess();
finish[process]=true;
executeprocess(process);
releaseresource();
}while(count<m);

printf("\n all proces executed correctly"); exit(0);


}

39
Part – VIII (Page replacement algorithms)

8.1 Simulation of FIFO page replacement algorithm

AIM : To simulate using a C program the FIFO page replacement algorithm.

PROCESS:

In a computer operating system that uses paging for virtual memory management, page
replacement algorithms decide which memory pages to page out (swap out, write to disk) when a
page of memory needs to be allocated. Paging happens when a page fault occurs and a free page
cannot be used to satisfy the allocation, either because there are none, or because the number of
free pages is lower than some threshold.
The first-in, first-out (FIFO) page replacement algorithm is a low-overhead algorithm that
requires little book-keeping on the part of the operating system. The idea is obvious from the name
– the operating system keeps track of all the pages in memory in a queue, with the most recent
arrival at the back, and the oldest arrival in front. When a page needs to be replaced, the page at the
front of the queue (the oldest page) is selected.

PROGRAM:

#include<stdio.h>
main()
{
int i,j,nof,nor,flag=0,ref[10],frm[10],pf=0,victim=-1;
system("clear");
printf("***** FIFO (First in first out) Page replacement algorithm ******\n");
printf("\n Enter no.of frames in memory : ");
scanf("%d",&nof);
printf("Enter number of pages required to process : ");
scanf("%d",&nor);
printf("Enter the pages numbers to load in sequence : ");
for(i=0;i<nor;i++)
scanf("%d",&ref[i]);
for(i=1;i<=nof;i++)
frm[i]=-1;
printf("\n");
for(i=0;i<nor;i++)
{
flag=0;
printf("\n\t Reference pn %d->\t",ref[i]);
for(j=0;j<nof;j++)
{
if(frm[j]==ref[i])
{
flag=1;
printf("already present in memory");

40
break;
}
}
if(flag==0)
{
pf++;
victim++;
victim=victim%nof;
frm[victim]=ref[i];
for(j=0;j<nof;j++)
printf("%4d",frm[j]);
}
}
printf("\n\n No.of pages faults : %d \n\n",pf);
}

OUTPUT:

41
8.2 Simulation of LRU page replacement algorithm

AIM : To simulate using a C program showing the LRU page replacement algorithm.

PROCESS:

In a computer operating system that uses paging for virtual memory management, page
replacement algorithms decide which memory pages to page out (swap out, write to disk) when a page of
memory needs to be allocated. Paging happens when a page fault occurs and a free page cannot be used to
satisfy the allocation, either because there are none, or because the number of free pages is lower than
some threshold.
LRU works on the idea that pages that have been most heavily used in the past few instructions are
most likely to be used heavily in the next few instructions too.

PROGRAM:

#include<stdio.h>
int i,j,nof,nor,flag=0,ref[10],frm[10],pf=0,victim=-1;
int recent[10],lrucal[10],count=0,tq[10];
int find();
int main()
{
system("clear");
printf("***** LRU (Least recently used) Page replacement algorithm ******\n");
printf("\n Enter no.of Frames in memory : ");
scanf("%d",&nof);
printf("\nEnter no.of pages required to load : ");
scanf("%d",&nor);
printf("\nEnter page numbers required to load in sequence : ");
for(i=0;i<nor;i++)
scanf("%d",&ref[i]);
for(i=0;i<nof;i++)
{
frm[i]=-1; tq[i]=0;
}
for(i=0;i<nor;i++)
{
count++;
flag=0;
printf("\n\t Reference pn%d->\t",ref[i]);
for(j=0;j<nof;j++)
{
if(frm[j]==ref[i])
{
flag=1;
tq[j]=count;
printf("already present in memory");
break;
}

42
}
if(flag==0)
{
pf++;
if(pf<=nof)
victim=(victim+1)%nof;
else
victim=find();
tq[victim]=count;
frm[victim]=ref[i];
for(j=0;j<nof;j++)
printf("%4d",frm[j]);
}
}
printf("\n\n No.of page faults : %d \n\n",pf);
}

int find()
{
int i,index=0,temp=tq[0];
for(i=1;i<nof;i++)
{
if(temp>tq[i])
{
temp=tq[i];
index=i;
}
}
return index;
}

OUTPUT:

43
Part – IX (Disk Scheduling algorithms)

9.1 Simulation of FCFS Disk Scheduling Algorithm


Input the maximum number of cylinders and work queue and its head starting position.
First Come First Serve Scheduling (FCFS) algorithm – The operations are performed in order
requested

● There is no reordering of the work queue.


● Every request is serviced, so there is no starvation
● The seek time is calculated.

PROGRAM:

#include<stdio.h>
int main()
{
int queue[20],n,head,i,j,k,seek=0,max,diff;
float avg;
printf("Enter the max range of disk\n");
scanf("%d",&max);
printf("Enter the size of queue request\n");
scanf("%d",&n);
printf("Enter the queue of disk positions to be read\n");
for(i=1;i<=n;i++)
scanf("%d",&queue[i]);
printf("Enter the initial head position\n");
scanf("%d",&head);
queue[0]=head;
for(j=0;j<=n-1;j++)
{
diff=abs(queue[j+1]-queue[j]);
seek+=diff;
printf("Disk head moves from %d to %d with seek %d\n”, queue[j],queue[j+1],
diff);
}
printf("Total seek time is %d\n",seek);
avg=seek/(float)n;
printf("Average seek time is %f\n",avg);
return 0;
}

OUTPUT:

44
9.2 Simulation of SSTF Disk Scheduling algorithm

In SSTF (Shortest Seek Time First), requests having the shortest seek time are executed first. So, the seek time of
every request is calculated in advance in the queue and then they are scheduled according to their calculated seek
time. As a result, the request near the disk arm will get executed first. SSTF is certainly an improvement over FCFS
as it decreases the average response time and increases the throughput of system.

PROGRAM:

#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
int queue[100],t[100],head,seek=0,n,i,j,temp;
float avg;
// clrscr();
printf("*** SSTF Disk Scheduling Algorithm ***\n");
printf("Enter the size of Queue\t");
scanf("%d",&n);
printf("Enter the Queue\t");
for(i=0;i<n;i++)
{
scanf("%d",&queue[i]);
}
printf("Enter the initial head position\t");
scanf("%d",&head);
for(i=1;i<n;i++)
t[i]=abs(head-queue[i]);
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(t[i]>t[j])
{
temp=t[i];
t[i]=t[j];
t[j]=temp;
temp=queue[i];
queue[i]=queue[j];
queue[j]=temp;
}
}
}
for(i=1;i<n-1;i++)
{
seek=seek+abs(head-queue[i]);
head=queue[i];
}
printf("\nTotal Seek Time is%d\t",seek);

45
avg=seek/(float)n;
printf("\nAverage Seek Time is %f\t", avg);
getch();
}

OUTPUT:

46

You might also like