0% found this document useful (0 votes)
25 views

Operating System Lab Manual

Uploaded by

frenzyganu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

Operating System Lab Manual

Uploaded by

frenzyganu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

Operating System

OS - Lab - SEM IV
(CSL403)

Name: Aiman Ansari


Roll Number: 272
Class: SEB

Practical 1
Aim: Explore basic Linux Commands and System Calls
Theory:

The Linux command line is a text interface to your computer. Often referred to as the
shell,terminal, console, prompt or various other names,it can give the appearance of being
complex and confusing to use but once you understand it, it’s really easy and helpful.

● ls - list directory contentsList information about the FILEs (the current directory by
default). Sort entries alphabetically if none of -cftuvSUX nor --sort isspecified.

● mkdir - creates a directory with given nameCreate the DIRECTORY(ies), if they


do not already exist.

● cd - change the working directoryThe cd utility shall change the working directory
of the current shell executionenvironment

● ps - report a snapshot of the current processes.ps displays information about a


selection of the active processes. If you want a repetitive update of the selection
and the displayed information, use top instead.

● grep, egrep, fgrep - print lines that match patterns.

grep searches for PATTERNS in each FILE. PATTERNSis one or more patterns
separated by newline characters, and grep prints each line that matches a
pattern.Typically PATTERNS should be quoted when grep is use din a shell command.

● getuid, geteuid - get user identity


getuid() returns the real user ID of the calling process.geteuid() returns the
effective user ID of the calling process.

● setuid - set user identity

setuid() sets the effective user ID of the calling process. If the calling process is
privileged (more precisely: if the process has theCAP_SETUID capability in its user
namespace), the real UID and saved set-user-ID arealso set.
● sort - sort lines of text files
Write sorted concatenation of all FILE(s) to standardoutput. With no FILE, or
whenFILE is -, read standard input.

● | - pipelining
A pipe is a form of redirection (transfer of standardoutput to some other
destination)that is used in Linux and other Unix-like operating systems to send the output
of one command/program/process to another command/program/process for further
processing.

● rm - remove files or directories


If the -I or --interactive=once option is given, and there are more than
three files or the -r, -R, or --recursive are given, then rm prompts the user for
whether to proceed with the entire operation. If the response is not affirmative,
the entire command is aborted.

● cal - display a calendar


cal displays a simple calendar. If no arguments are specified, the current month
isdisplayed. The month may be specified as a number(1-12), as a month name
or as an abbreviated month name according to the current locales.

● time - get time in seconds


time() returns the time as the number of seconds since the Epoch,
1970-01-0100:00:00 +0000 (UTC).13.pwd - print name of current/working
directoryPrint the full filename of the current working directory
Conclusion:
We have seen different Linux commands and executed them to see how it interacts with
the system; commands like creating directory, creating and deleting files, etc.

Practical 2
Aim: Linux Shell Script
● Display OS version, release number, kernel version
● Display top 10 processes in descending order
● Display processes with the highest memory usage
● Display current logged in user and log name

Theory:
A shell is a command-line interpreter and typical operations performed by shell script
include file manipulation, program execution, and printing text.

● Display OS version, release number, kernel version

Linux command displays system information like NAME, VERSION, ID and even
VERSION_ID among other things. Since Nix systems like to be command bases, there
are many commands which helps in our need.

● Display top 10 processes in descending order

This command displays top 10 processes, there are flags that enable display
more precise information like pid, ppid, %mem and we’ve used --sortflag to sort
the output according to%mem i.e memory usage and we’ve pipelined it to head
to display 10 processes.

● Display processes with the highest memory usage:

It displays the highest memory usage process in the system, as you can see from
the below posted image, it's currently firefox browser.

● Display current logged in user and log name

whoami displays current user and other commands have been executed to
display current BASH SHELL and pwd displays current working directory.
Program:
#!/bin/sh

echo "--------------------"
echo "Shell Script OSL Practical 2"
echo "OS INFO: "
cat /etc/os-release
uname -r
uname -a
uname -v

echo "--------------------------------"

echo "10 Processes in descending order: " ps -eo


pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -10 echo
"--------------------------------"

echo "Highest Memory Usage: "


ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -2
echo "--------------------------------"
echo "User Login and Name: "

whoami
logname
echo "$SHELL"
pwd
uname -srm
echo "--------------------------------"
OUTPUT:

Practical 3
Aim: Linux -API Implementing “CP” command
Theory:
Implementing linux “cp” command to copy one file to another

Description:

Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

Mandatory arguments to long options are mandatory for short options too.
-a, --archive same as -dR --preserve=all
--attributes -only don't copy the file data, just the attributes
--backup make a backup of each existing destination file
-b like --backup but does not accept an argument

Program:

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

int main(){
FILE *fptr1, *fptr2;
char filename[100],c;
printf("Enter the filename to open for reading\n");
scanf("%s",filename);// Open one file for reading
fptr1=fopen(filename,"r");

if(fptr1==NULL){
printf("Cannot open file %s\n", filename);
exit(0);
}
printf("Enter the filename to open for writing\n");
scanf("%s",filename);
fptr2=fopen(filename,"w");

if(fptr2==NULL){
printf("Cannot open file %s\n",filename);
exit(0);
}
c=fgetc(fptr1);
while(c!=EOF){
fputc(c,fptr2);
c=fgetc(fptr1);
}
printf("\nContents copied to %s",filename);
fclose(fptr1);
fclose(fptr2);
return 0;
}
OUTPUT:
Practical 4
Aim: To create a child process using fork system call. Obtain process ID of both child
and parent using getpid and getppid system call.

Theory:

Fork system call is used for creating a new process, which is called a child process,
which runs concurrently with the process that makes the fork() call (parent process).
After a new child process is created, both processes will execute the next instruction
following the fork() system call. A child process uses the same pc (program counter),
same CPU registers, same open files which are used in the parent process.

It takes no parameters and returns an integer value.Below are different values returned by
fork().
● Negative Value: creation of a child process was unsuccessful.
● Zero: Returned to the newly created child process.
● Positive value: Returned to parent or caller. The value contains the process ID of
the newly created child process.

Syntax for fork() system call is : Int pid=fork(); This is used to create a new process
which becomes the child process of fork call process(parent process) Later both will
execute together.
Syntax for getpid :getpid(); It is used to print the process Id of current process or
childprocess.

Syntax for getppid: getppid(); It is used to print the process Id(PID) of the parent process
Program:
#include <stdio.h>
#include <stdlib.h>
int fork();
int getpid();
int getppid();

int main() {
int pid = fork();
if (pid == 0) {
printf("This is the child process. My pid is %d and my parent's id is
%d.\n",
getpid(),
getppid());
}
else {
printf("This is the parent process. My pid is %d and my parent's id is
%d.\n",
getpid(),
pid);
}
return 0;
}

OUTPUT:
Practical 5
Aim: Process management: Scheduling
● Write a program to demonstrate the concept of non-preemptive scheduling
algorithms.
● Write a program to demonstrate the concept of preemptive scheduling
algorithms.
Theory:
1. Non Preemptive Scheduling:

Preemptive scheduling is used when a process switches from running state to ready
state or from waiting state to ready state. The resources (mainly CPU cycles) are
allocated to the process for a limited amount of time and then are taken away, and the
process is again placed back in the ready queue if that process still has CPU burst time
remaining. That process stays in the ready queue till it gets its next chance to execute.

2. Preemptive Scheduling:

Non-preemptive Scheduling is used when a process terminates, or a process switches


from running to waiting state. In this scheduling, once the resources (CPU cycles) are
allocated to a process, the process holds the CPU till it gets terminated or it reaches a
waiting state. In case of non-preemptive scheduling it does not interrupt a process
running CPU in the middle of the execution. Instead, it waits till the process completes
its CPU burst time and then it can allocate the CPU to another process.
Non-Preemptive Scheduling:
Program:

#include<stdio.h>

int main(){
int burst_time[20], process[20], waiting_time[20], turnaround_time[20],
priority[20];
int i, j, limit, sum = 0, position, temp;
float average_wait_time, average_turnaround_time;
printf("Enter Total Number of Processes:\t");
scanf("%d", &limit);
printf("\nEnter Burst Time and Priority For %d Processes\n", limit);
for(i = 0; i < limit; i++) {
printf("\nProcess[%d]\n", i + 1);
printf("Process Burst Time:\t");
scanf("%d", &burst_time[i]);
printf("Process Priority:\t");
scanf("%d", &priority[i]);
process[i] = i + 1;
}

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


position = i;

for(j = i + 1; j < limit; j++){


if(priority[j] < priority[position]){
position = j;
}
}
temp = priority[i];
priority[i] = priority[position];
priority[position] = temp;
temp = burst_time[i];
burst_time[i] = burst_time[position];
burst_time[position] = temp;
temp = process[i];
process[i] = process[position];
process[position] = temp;
}
waiting_time[0] = 0;

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


waiting_time[i] = 0;
for(j = 0; j < i; j++){
waiting_time[i] = waiting_time[i] + burst_time[j];
}
sum = sum + waiting_time[i];
}
average_wait_time = sum / limit;
sum = 0;
printf("\nProcess ID\t\tBurst Time\t Waiting Time\t Turnaround Time\n");
for(i = 0; i < limit; i++) {
turnaround_time[i] = burst_time[i] + waiting_time[i];
sum = sum + turnaround_time[i];
printf("\nProcess[%d]\t\t%d\t\t %d\t\t %d\n", process[i],
burst_time[i], waiting_time[i], turnaround_time[i]);
}
average_turnaround_time = sum / limit;
printf("\nAverage Waiting Time:\t%f", average_wait_time);
printf("\nAverage Turnaround Time:\t%f\n", average_turnaround_time);
return 0;
}
OUTPUT:

Preemptive Scheduling:

Program:

#include<stdio.h>
#define executed 1
#define not_exec 0

typedef struct process {


int arr; //arrival time
int bt; //burst time
int wt; //waiting time
int ft; //finish time
int status;
} process;

void srtf(process *pr,int n,float *awt,float *atat);


int shortestProcess(process *pr,int n,int ct);
int sumArray(int *arr,int n);
void dispArray(int *arr,int n);

int main() {
int n,i;
float awt,atat;
process pr[20];
printf("\nEnter the no. of processes:");
scanf("%d",&n);

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


printf("\nEnter the arrival and burst time of process %d: ",i+1);
scanf("%d %d",&pr[i].arr,&pr[i].bt);
}
srtf(pr,n,&awt,&atat);
printf("\nThe average waiting time(AWT)=%.2f",awt);
printf("\nThe average turnaround time(ATAT)=%.2f\n",atat);
return 0;
}
void srtf(process *pr,int n,float *awt,float *atat) {
int i,ct=0,spi; //ct->current time,spi->shortest process index
for(i=0;i<n;i++) {
pr[i].status=not_exec;
pr[i].wt=0;
}
do{
spi=shortestProcess(pr,n,ct);
if(spi==-1)
break;
for(i=0;i<n;i++) {
if(i!=spi && pr[i].status!=executed && ct>=pr[i].arr)
pr[i].wt++;
}
ct++; //updating current time
pr[spi].ft=ct-pr[spi].arr; //finish time of the executed process
pr[spi].bt--;
if(pr[spi].bt<=0){
pr[spi].status=executed;
pr[spi].ft=ct-pr[spi].arr;
}
}while(ct);
for(i=0;i<n;i++) {
(*awt)+=pr[i].wt;
(*atat)+=pr[i].ft;
}
*awt=*awt/n;
*atat=*atat/n;
printf("\nWaiting Times:");
for(i=0;i<n;i++) {
printf("\t%d",pr[i].wt);
}
printf("\nturnaround Times:");
for(i=0;i<n;i++) {
printf("%d\t",pr[i].ft);
}
}

int shortestProcess(process *pr,int n,int ct){


int i,min_bt=99999,min_index=-1;
for(i=0;i<n;i++) {
if(pr[i].status==not_exec && pr[i].arr<=ct) {
if(pr[i].bt<min_bt) {
min_bt=pr[i].bt;
min_index=i;
}
}
}
return min_index;
}
int sumArray(int *arr,int n){
int sum=0,i;
for(i=0; i<n; i++) {
sum+=arr[i];
}
return sum;
}

void dispArray(int *arr,int n){


int i=0;
for(i=0; i<n; i++) {
printf("%d",arr[i]);
}
}
OUTPUT:
Practical 6
Aim: Write a C program to implement a solution to the Producer consumer problem
through Semaphore.

Theory:

A semaphore S is an integer variable that can be accessed only through two standard
operations : wait() and signal().
The wait() operation reduces the value of semaphore by 1 and the signal() operation
increases its value by 1.

Semaphores are of two types:


1. Binary Semaphore – This is similar to mutex lock but not the same thing. It can
have only two values – 0 and 1. Its value is initialized to 1. It is used to implement
the solution of critical section problems with multiple processes.
2. Counting Semaphore – Its value can range over an unrestricted domain. It is used
to control access to a resource that has multiple instances.

We have a buffer of fixed size. A producer can produce an item and can place it in the
buffer. A consumer can pick items and can consume them. We need to ensure that when a
producer is placing an item in the buffer, then at the same time the consumer should not
consume any item. In this problem, the buffer is the critical section.

To solve this problem, we need two counting semaphores – Full and Empty. “Full” keeps
track of the number of items in the buffer at any given time and “Empty” keeps track of
the number of unoccupied slots.
Program:
#include <stdio.h>
#include <stdlib.h>
int mutex = 1;
int full = 0;
int empty = 10, x = 0;

void producer() {
--mutex;
++full;
--empty;
x++;
printf("\nProducer produces" "item %d", x);
++mutex;
}
void consumer() {
--mutex;
--full;
++empty;
printf("\nConsumer consumes "
"item %d", x);
x--;
++mutex;
}
int main() {
int n, i;
printf("\n1. Press 1 for Producer"
"\n2. Press 2 for Consumer"
"\n3. Press 3 for Exit");
for (i = 1; i > 0; i++) {
printf("\nEnter your choice:");
scanf("%d", &n);

switch (n) {
case 1:

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


producer();
} else {
printf("Buffer is full!");
}
break;
case 2:
if ((mutex == 1) && (full != 0)) {
consumer();
} else {
printf("Buffer is empty!");
}
break;
case 3:
exit(0);
break;
}
}
}
OUTPUT:

Practical 7
Aim: Write a program to demonstrate the concept of deadlock avoidance through
Banker’s Algorithm.

Theory:

The resource-allocation-graph algorithm is not applicable to a resource-allocation


system with multiple instances of each resource type. The deadlock-avoidance algorithm that
we describe next is applicable to such a system but is less efficient than the
resource-allocation graph scheme. This algorithm is commonly known as the banker’s
algorithm.

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

● Available. A vector of length m indicates the number of available resources of each


type. If Available[j] equals k, then k instancesof resource type R jare available.

● Max. An n × m matrix defines the maximum demand of each process.If Max[i][j]


equals k, then process P i may request at most k instances of resource type R j

● Allocation. An n × m matrix defines the number of resources of each type currently


allocated to each process. If Allocation[i][j]equals k, then processP i is currently
allocated k instances of resourcetype R j

● Need. An n × m matrix indicates the remaining resources needed for each process. If
Need[i][j] equals k, then process P imay need k more instances of resource type R j to
complete its task. Note thatNeed[i][j] equals Max[i][j]− Allocation[i][j]
Program:

#include <stdio.h>
int main() {
int n, m, i, j, k;
n = 5; // Number of processes
m = 3; // Number of resources
int alloc[5][3] = { { 0, 1, 0 }, // P0 // Allocation Matrix {
2, 0, 0 }, // P1
{ 3, 0, 2 }, // P2
{ 2, 1, 1 }, // P3
{ 0, 0, 2 } }; // P4

int max[5][3] = { { 7, 5, 3 }, // P0 // MAX Matrix


{ 3, 2, 2 }, // P1
{ 9, 0, 2 }, // P2
{ 2, 2, 2 }, // P3
{ 4, 3, 3 } }; // P4

int avail[3] = { 3, 3, 2 }; // Available Resources


int f[n], ans[n], ind = 0;
for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {

int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
return (0);
}
OUTPUT:

Practical 8
Aim: Write a program to demonstrate the concept of dynamic partitioning placement
algorithms i.e., Best Fit, First Fit, Worst-Fit etc.

Theory:
This procedure is a particular instance of the general dynamic storage-allocation problem,
which concerns how to satisfy a request of size n from a list of free holes. There are many
solutions to this problem. The first-fit, best-fit, and worst-fit strategy are the ones most
commonly used to select a freehold from the set of available holes.

● First fit: Allocate the first hole that is big enough.Searching can start either at the
beginning of the set of holes or at the location where the previous first-fit search
ended. We can stop searching as soon as we find a free holethat is large enough.

● Best fit: Allocate the smallest hole that is big enough. We must search the entire list,
unless the list is ordered by size. This Strategy produces the smallest leftover hole.
● Worst fit: Allocate the largest hole. Again, we must search the entire list,unless it is
sorted by size. This strategy produces the largest leftover hole,which may be more
useful than the smaller leftoverhole from a best-fit approach

Simulations have shown that both first fit and best fit are better than worst fit in terms of
decreasing time and storage utilization.Neither first fit nor bestfit is clearly better than the
other in terms of storage utilization, but first fit is generally faster.
Best Fit Algorithm

Program:

#include<stdio.h>
#define max 25
int main(){
int frag[max],b[max],f[max],i,j,nb,nf,temp,lowest=10000;
static int bf[max],ff[max];
printf("\nEnter the number of blocks:");
scanf("%d",&nb);
printf("Enter the number of files:");
scanf("%d",&nf);
printf("\nEnter the size of the blocks:-\n");
for(i=1;i<=nb;i++) {
printf("Block %d:",i);
scanf("%d",&b[i]);
}
printf("Enter the size of the files :-\n");
for(i=1;i<=nf;i++) {
printf("File %d:",i);
scanf("%d",&f[i]);
}
for(i=1;i<=nf;i++) {
for(j=1;j<=nb;j++) {
if(bf[j]!=1) {
temp=b[j]-f[i];
if(temp>=0)
if(lowest>temp) {
ff[i]=j;

lowest=temp;
}
}
}
frag[i]=lowest;
bf[ff[i]]=1;
lowest=10000;
}
printf("\nFile No\tFile Size \tBlock No\tBlock Size\tFragment");
for(i=1;i<=nf && ff[i]!=0;i++)
printf("\n%d\t\t%d\t\t%d\t\t%d\t\t%d",i,f[i],ff[i],b[ff[i]],frag[i]);
}
OUTPUT:
First Fit Algorithm

Program:

#include<stdio.h>
int main() {
// Declare Variables
int nb,blockSize[100],n,jobSize[100],i,j,alloc[100];

//Input initial values


printf("Enter the number of available memory blocks: ");
scanf("%d",&nb);
printf("Enter the size of each memory block: \n");
for(i=0;i<nb;i++) {
printf("Size of block%d: ",i+1);
scanf("%d",&blockSize[i]);
}

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


scanf("%d",&n);
printf("Enter the size of each process: \n");
for(i=0;i<n;i++) {
printf("Size of process%d: ",i+1);
scanf("%d",&jobSize[i]);
}

for(i=0;i<n;i++) {
alloc[i] = -1;
}

// Allocate the processes


for(i=0;i<n;i++){
for(j=0;j<nb;j++) {
if(blockSize[j]>jobSize[i]) {
alloc[i]=j;
j=nb;
blockSize[j]=0;
}
}
}

// Print the results


printf("Process P of {size} is allocated to block \n");
for(i=0;i<n;i++) {
if(alloc[i]!=-1)
printf("Process %d of %d --> Block
%d\n",i+1,jobSize[i],alloc[i]+1);
else
printf("Process %d of %d --> is not allocated \n",i+1,jobSize[i]);
}
}
OUTPUT:

Worst Fit Algorithm

Program:

#include<stdio.h>
int main()
{
int fragments[10], blocks[10], files[10];
int m, n, number_of_blocks, number_of_files, temp, top = 0;
static int block_arr[10], file_arr[10];
printf("\nEnter the Total Number of Blocks:\t");
scanf("%d",&number_of_blocks);
printf("Enter the Total Number of Files:\t");
scanf("%d",&number_of_files);
printf("\nEnter the Size of the Blocks:\n");
for(m = 0; m < number_of_blocks; m++)
{
printf("Block No.[%d]:\t", m + 1);
scanf("%d", &blocks[m]);
}
printf("Enter the Size of the Files:\n");
for(m = 0; m < number_of_files; m++)
{
printf("File No.[%d]:\t", m + 1);
scanf("%d", &files[m]);
}
for(m = 0; m < number_of_files; m++)
{
for(n = 0; n < number_of_blocks; n++)
{
if(block_arr[n] != 1)
{
temp = blocks[n] - files[m];
if(temp >= 0)
{
if(top < temp){
file_arr[m] = n;
top = temp;
}
}
}
fragments[m] = top;
block_arr[file_arr[m]] = 1;
top = 0;
}
}
printf("\nFile Number\tFile Size\tBlock Number\tBlock Size\tFragment");
for(m = 0; m < number_of_files; m++)
{
printf("\n%d\t\t%d\t\t%d\t\t%d\t\t%d", m, files[m], file_arr[m],
blocks[file_arr[m]], fragments[m]);
}
printf("\n");
return 0;
}
OUTPUT:
Practical 9

Aim: Write a program in C demonstrate the concept of page replacement policies for
handling page faults eg: FIFO, LRU etc.

Theory:

● FIFO Page Replacement:

The simplest page-replacement algorithm is a first-in,first-out (FIFO) algorithm.A FIFO


replacement algorithm associates with each page the time when that page was brought
into memory. When a page must be replaced, the oldest page is chosen. Notice that it is
not strictly necessary to record the time when the page is brought in. We can create a
FIFO queue to hold all pages in memory.We replace the page at the head of the queue.
When A page is brought into memory, we insert it at the tail of the queue.

The FIFO page-replacement algorithm is easy to understand and program.However, its


performance is not always good. On the one hand, the page replaced may be an
initialization module that was used a long time ago and is no longer needed. On the other
hand, it could contain a heavily used variable that was initialized early and is in constant
use.

● LRU Page Replacement:

If the optimal algorithm is not feasible, perhaps an approximation of the optimal


algorithm is possible. The key distinction between the FIFO and OPTalgorithms (other
than looking backward versus forward in time) is that theFIFO algorithm uses the time
when a page was brought into memory, whereasthe OPT algorithm uses the time when a
page is tobe used. If we use the recent past as an approximation of the near future, then
we can replace the page that has not been used for the longest period of time.This
approach is the least recently used (LRU) algorithm.

LRU replacement associates with each page the times of that page’s last use.When a page
must be replaced, LRU chooses the page that has not been used for the longest period of
time. We can think of this strategy as the optimal page-replacement algorithm looking
backward in time,rather than forward.(Strangely, if we let SR be the reverse of a
reference string S, then the page-fault rate for the OPT algorithm on S is the same as the
page-fault rate for the OPTalgorithm on S R . Similarly, the page-fault rate for the LRU
algorithm on S is the same as the page-fault rate for the LRU algorithm on SR .)
FIFO Page Replacement:

Program:

#include<stdio.h>
#include<string.h>
int main() {
int n,l,i,j,count=0,temp=1;
char page[100],sent[100];
printf("Enter the number of pages: ");
scanf("%d",&n);
printf("Enter then input string: ");
scanf("%s",sent);
l=strlen(sent);

for(i=0;i<l;i++) {
for(j=0;j<n;j++)
if(sent[i] == page[j])
temp=0;
if(temp==1) {
page[count%n] = sent[i];
count++;
}
temp=1;
}
printf("The number of page faults are: %d",count);
printf("\nThe number of page hits are: %d\n",l - count);
}
OUTPUT:
LRU Page Replacement:

Program:

#include<stdio.h>
#include<string.h>
int main() {
char ip[100],page[100];
int n,l,i,j,w,k,count=0,recentNo[100],hit=0,temp=1,min;
printf("Enter the input string: ");
scanf("%s",ip);
l = strlen(ip);
printf("Enter the number of pages: ");
scanf("%d",&n);
for(i=0;i<n;i++) {
page[i]=ip[i];
recentNo[i] = -1;
count++;
}
for(i=n;i<l;i++) {
for(j=0;j<n;j++) {
if(page[j] == ip[i]) {
hit++;
temp=0;
}
}
if(temp == 1) {
for(j=0;j<n;j++) {
for(k=i-1;k>=0;k--) {
if(page[j]==ip[k]) {
recentNo[i] = k;
k=0;
}
}
}
min = 0;
for(j=0;j<n;j++) {
if(recentNo[min]>recentNo[j])
min = j;
}
page[min] = ip[i];
count++;

}
temp=1;
for(j=0;j<n;j++) {
recentNo[i] = -1;
}
}

printf("The number of page faults are: %d\n",count);


printf("The number of page hits are: %d\n",l - count);
}
OUTPUT:

Practical 10
Aim: Write a program in C to do disk scheduling - FCFS, SCAN, C-SCAN

Theory:

● First Come First Serve (FCFS):

The simplest form of disk scheduling is, of course, the first-come, first-served(FCFS)
algorithm. This algorithm is intrinsically fair, but it generally does not provide the fastest
service.

Example:
Suppose the order of request is- (82,170,43,140,24,16,190)
And current position of Read/Write head is : 50

So, total seek time:


=(82-50)+(170-82)+(170-43)+(140-43)+(140-24)+(24-16)+(190-16)
=642
● SCAN:

In the SCAN algorithm, the disk arm starts at one end of the disk and moves toward the
other end, servicing requests as it reaches each cylinder, until it gets to the other end of
the disk. At the other end, the direction of head movement is reversed, and servicing
continues. The head continuously scans back and forth across the disk.
The SCAN algorithm is sometimes called the elevator algorithm, since the disk arm
behaves just like an elevator in a building, first servicing all the requests going up and
then reversing to service requests the other way.

Suppose the requests to be addressed are-82,170,43,140,24,16,190.And theRead/Write


arm is at 50, and it is also given that the disk arm should move “towards the larger
value”.

Therefore, the seek time is calculated as:


=(199-50)+(199-16)
=332
● Circular-SCAN (C-SCAN):

Circular SCAN (C-SCAN) scheduling is a variant ofSCAN designed to provide more


uniform wait time. Like SCAN, C-SCAN moves the head from one end of the disk to the
other, servicing requests along the way. When the head reaches the other end, however, it
immediately returns to the beginning of the disk without servicing any requests on the
return trip (Figure below).

The C-SCAN scheduling algorithm essentially treats the cylinders as a circular list that
wraps around from the final cylinder to the firstone.

Suppose the requests to be addressed are-82,170,43,140,24,16,190.


And theRead/Write arm is at 50, and it is also given that the disk arm should move
“towards the larger value”.
Seek time is calculated as:
=(199-50)+(199-0)+(43-0)
=391
First Come First Serve

Program:

#include<stdio.h>
int main() {

// Variable declaration
int nc,nt,head,track[100],i,j,distance=0;

// Read the initial values


printf("Enter the number of cylinders (0 to n-1): n = ");
scanf("%d",&nc);
printf("Enter the number of requested tracks: ");
scanf("%d",&nt);
printf("Enter the current location of pointer head: ");
scanf("%d",&head);
track[0] = head;
printf("Enter the requested tracks in FIFO order: \n");
for(i=1;i<=nt;i++) {
scanf("%d",&track[i]);
}

// Display the order in which requested tracks are processed


printf("The requested tracks are processed in order: %d -> ",head);
for(i=1;i<=nt;i++) {
if(i!=nt)
printf("%d -> ",track[i]);
else
printf("%d \n",track[i]);
}

// find the seek distance


for(i=0;i<nt;i++) {
if(track[i]>track[i+1]) {
distance+=track[i]-track[i+1];
} else {
distance+=track[i+1]-track[i];
}
}

// Display the result


printf("The total seek distance is %d cylinders\n",distance);
}
OUTPUT:

SCAN:

Program:
#include<stdio.h>
int main() {

// Declare the variable


int nc,nt,head,track[100],i,j,dist=0,temp,headPos;

// Read the initial values


printf("Enter the number of cylinders (0 to n-1): n = ");
scanf("%d",&nc);
printf("Enter the number of requested tracks: ");
scanf("%d",&nt);
printf("Enter the current location of pointer head: ");
scanf("%d",&head);
track[0] = head;
printf("Enter the requested tracks in FIFO orider: \n");
for(i=1;i<=nt;i++) {
scanf("%d",&track[i]);
// check whether the requested track lies in the cylinder range
if(track[i]>=nc || track[i]<0) {
printf("INVALID INPUT!!! ABORTING!!");
return(0);
}
}
nt++;
track[nt] = nc-1;

// process the requests according to SCAN algorithm


// requests are processed first in right direction
for(i=0;i<=nt;i++) {
for(j=i;j<=nt;j++) {
if(track[i]>track[j]) {
temp = track[i];
track[i] = track[j];
track[j] = temp;
}
}
}
for(i=0;i<=nt;i++)
if(track[i] == head){
headPos = i;
break;
}
dist = (track[nt]-track[headPos])+(track[nt]-track[0]);
printf("The total seek distance is: %d \n",dist);
}
OUTPUT:
C-SCAN:

Program:

#include<stdio.h>
int main() {

// Declare the variable


int nc,nt,head,track[100],i,j,dist=0,temp,headPos;

// Read the initial values


printf("Enter the number of cylinders (0 to n-1): n = ");
scanf("%d",&nc);
printf("Enter the number of requested tracks: ");
scanf("%d",&nt);
printf("Enter the current location of pointer head: ");
scanf("%d",&head);
track[0] = head;
printf("Enter the requested tracks in FIFO orider: \n");
for(i=1;i<=nt;i++) {
scanf("%d",&track[i]);
// check whether the requested track lies in the cylinder range
if(track[i]>=nc || track[i]<0) {
printf("INVALID INPUT!!! ABORTING!!");
return(0);
}
}
nt++;
track[nt] = nc-1;

// process the requests according to C-SCAN algorithm


// requests are processed first in right direction
for(i=0;i<=nt;i++) {
for(j=i;j<=nt;j++) {
if(track[i]>track[j]) {
temp = track[i];
track[i] = track[j];
track[j] = temp;
}
}
}
for(i=0;i<=nt;i++)
if(track[i] == head){
headPos = i;
break;
}
dist = (track[nt]-track[headPos])+(track[nt]-0)+(track[headPos-1]-0);
printf("The head position is: %d \n",track[headPos]);
printf("The total seek distance is: %d cylinders\n",dist);
}
OUTPUT:

You might also like