You are on page 1of 53

OPERATING SYSTEMS LAB MANUAL

III-I R-13

VSM COLLEGE OF ENGINEERING

OPERATING SYSTEMS LAB MANUAL


INDEX
1.

2.
3.
4.

5.
6.

7.
8.
9.

10.

Simulate the following CPU scheduling algorithms


i. Round Robin
ii. SJF
iii. FCFS
iv. Priority
Loading executable programs into memory and execute system call implementation
read(),write(), open() and close()
Multiprogramming-Memory management implementation of fork(),wait(),exec() & exit() system
calls
Simulate all file allocation strategies
i. Sequential
ii. Indexed
iii. Linked
Simulate MVT and MFT
Simulate all File Organization Techniques
i. Single level directory
ii. Two level
iii. Hierarchical
iv. DAG
Simulate Bankers algorithm for deadlock avoidance
Simulate Bankers Algorithm for Deadlock prevention
Simulate all page replacement algorithms
i. FIFO
ii. LRU
iii. LFU Etc.
Simulate Paging Technique of memory management.

OPERATING SYSTEMS LAB MANUAL

III-I R-13

VSM COLLEGE OF ENGINEERING

1) Simulate the following CPU scheduling algorithms


a)
b)
c)
d)

FCFS
SJF
Priority
Round Robin

Description:
FCFS (first-come-first-serve) Scheduling
First-come, First served is simplest scheduling algorithm
Ready queue is a FIFO queue:
Longest waiting process at the front of queue
New ready processes join the rear
Non-preemptive: executes until voluntarily gives up CPU finished or waits for
some event
Problem: CPU bound process may require a long CPU burst
Other processes, with very short CPU bursts, wait in queue reduces CPU and I/O
device utilization

SJF (shortest-job-first) Scheduling


Assume the next burst time of each process is known
SJF selects process which has the shortest burst time
Optimal algorithm because it has the shortest average waiting time
Impossible to know in advance
OS knows the past burst times- make a prediction using an average
Non-preemptive Or preemptive
Shortest remaining time first
Interrupts running process if a new process enters the queue
New process must have shorter burst than remaining time

Round Robin Scheduling


Similar to FCFS, but preemption to switch between processes
Time quantum(time slice) is a small unit of time (10 to 100 ms)
Process is executed on the CPU for at most one time quantum
Implemented by using the ready queue as a circular queue
Head process gets the CPU
Uses less than a time quantum implies gives up the CPU voluntary
Uses full time quantum implies timer will cause an interrupt

Context switch will be executed


Process will be put at the tail of queue
Priority Scheduling
Assume a priority is associated with each process
2

OPERATING SYSTEMS LAB MANUAL

III-I R-13

VSM COLLEGE OF ENGINEERING

Assume all processes arrive at the same time


Select highest priority process from the ready queue
Let T be the next CPU burst of a process
SJF is a special case of priority scheduling
Equal-priority processes are scheduled in FCFS order
PRIORITY can be preemptive or Non-preemptive
Priorities can be defined internally
Memory requirements, number of open files, burst times
a) FCFS:
AIM: A program to simulate the FCFS CPU scheduling algorithm

PROGRAM:

#include<stdio.h>
#include<conio.h>
struct process
{
int at,ts,st,ft,ta;
float nta;
};
main()
{
struct process p[20];
int n,i,j;
float tamean=0,ntamean=0;
clrscr();
printf("\nEnter Number of Processes:: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nEnter Arrival Time for Process-%c :: ",65+i);
scanf("%d",&p[i].at);
printf("\nEnter Service Time for Process-%c :: ",65+i);
scanf("%d",&p[i].ts);
}
for(i=0;i<n;i++)
{
if(i==0)
p[i].st=p[i].at;
else
{
p[i].st=0;
for(j=0;j<i;j++)
p[i].st=p[i].st+p[j].ts;
}
p[i].ft=p[i].ts+p[i].st;
3

OPERATING SYSTEMS LAB MANUAL

III-I R-13

VSM COLLEGE OF ENGINEERING

p[i].ta=p[i].ft-p[i].at;
p[i].nta=(float)p[i].ta/p[i].ts;
tamean=tamean+p[i].ta;
ntamean=ntamean+p[i].nta;
}
tamean=(float)(tamean/n);
ntamean=(float)(ntamean/n);
printf("\nProcess AT ST StT FT TA NTA");
for(i=0;i<n;i++)
printf("\n%3c%12d%10d%10d%10d%10d
%15f",65+i,p[i].at,p[i].ts, p[i].st,p[i].ft,p[i].ta,p[i].nta);
printf("\n\n Mean of Turn-around time : %f",tamean);
printf("\n\n Mean of Normalized turn-around time : %f",ntamean);
getch();
}
Output:
Enter Number of Processes:: 3
Enter Arrival Time for Process-A :: 0
Enter Service Time for Process-A :: 12
Enter Arrival Time for Process-B :: 2
Enter Service Time for Process-B :: 9
Enter Arrival Time for Process-C :: 6
Enter Service Time for Process-C :: 14
Process
A
B
C

AT
0
2
6

ST
2
9
14

StT
FT
TA
NTA
0
12
12
1.000000
12
21
19
2.111111
21
35
29
2.071429

Mean of Turn-around time: 20.000000


Mean of Normalized turn-around time: 1.727513

b) SJF: AIM: A program to simulate the SJF CPU scheduling algorithm


#include<stdio.h>
#include<conio.h>
main()
{
int sbt[10],swt[10],st[10],stt[10],sft[10],n,i,j,wt,tt,temp;
float avgwt,avgtt;
wt=0;tt=0;temp=0;st[1]=0;
clrscr();
printf("enter no.of jobs");
scanf("%d",&n);
printf("enter the burst times of jobs");
for(i=1;i<=n;i++)
scanf("%d",&sbt[i]);
for(i=1;i<=(n-1);i++)
for(j=i+1;j<=n;j++)
if((sbt[i]>sbt[j])&&(sbt[i]!=sbt[j]))
{
temp=sbt[i];
sbt[i]=sbt[j];
sbt[j]=temp;
}
for(i=1;i<=n;i++)
{
st[i+1]=st[i]+sbt[i];
sft[i]=st[i]+sbt[i];
if(i==1)
swt[i]=0;
else
swt[i]=swt[i-1]+sbt[i-1];
stt[i]=swt[i]+sbt[i];
wt=wt+swt[i];
tt=tt+stt[i];
}
avgwt=((float)wt/(float)n);
avgtt=((float)tt/(float)n);
printf("\nJOB sert
st
wt
ft
turt");
for(i=1;i<=n;i++)
printf("\nJ%d\t%d\t%d\t %d\t%d\t%d\n",i,sbt[i],st[i],sft[i],swt[i],stt[i]);
printf("\navg waiting time=%0.2f,turnover total
time=%0.2f",avgwt,avgtt);
getch();
}

Output:
enter no.of jobs3
enter the burst times of jobs4

JOB sert
st
wt
ft
turt
J1
4
0
4
0
4
J2
5
4
9
4
9
J3
6
9
15
9
15
avg waiting time=4.33,turnover total time=9.33

c) Priority:
AIM: A program to simulate the priority CPU scheduling algorithm
PROGRAM:
#include<stdio.h>
#include<conio.h>
struct process
{
int ts,pri,wait,ft;
}p[20];
main()
{
int n,pri1[20],i,j,temp,ft1[25];
clrscr();
printf("\n Enter Number of Processes:: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nEnter Service Time for Process-%c : ",65+i);
scanf("%d",&p[i].ts);
printf("\nEnter Priority for Process-%c : ",65+i);
scanf("%d",&p[i].pri);
}
for(i=0;i<n;i++)
pri1[i]=p[i].pri;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(pri1[i]>pri1[j])
{
temp=pri1[i];
pri1[i]=pri1[j];
pri1[j]=temp;
}
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(pri1[i]==p[j].pri)
{
if(i==0)
{
p[j].wait=0;
p[j].ft=p[j].ts;
ft1[i]=p[j].ft;
}
else
{
p[j].ft=ft1[i-1]+p[j].ts;

p[j].wait=ft1[i-1];
ft1[i]=p[j].ft;
}
}
}
}
printf("\nProcess ST
PRI
FT WT ");
for(i=0;i<n;i++)
{
printf("\nprocess-%c%10d%13d%14d
%15d",65+i,p[i].ts,p[i].pri,p[i].ft,p[i].wait);
}
getch();
}
Output:
Enter Number of Processes:: 3
Enter Service Time for Process-A : 5
Enter Priority for Process-A : 2
Enter Service Time for Process-B : 8
Enter Priority for Process-B : 1
Enter Service Time for Process -C : 6
Enter Priority for Process-C : 3
Process
process-A
process-B
process-C

ST
5
8
6

PRI
2
1
3

FT
13
8
19

WT
8
0
13

d) Round Robin:
AIM: A program to simulate the Round Robin CPU scheduling algorithm
PROGRAM:
#include<stdio.h>
#include<conio.h>
struct process
{
int at,ts,st,ft,wait,ts2,ta;
float nta;
}p[20];
main()
{
int i,j,slice,n;
float tamean=0,ntamean=0;
clrscr();
printf("Enter Number of Processes :: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nEnter Arrival Time for Process-%c : ",65+i);
scanf("%d",&p[i].at);
printf("\nEnter Service Time for process-%c : ",65+i);
scanf("%d",&p[i].ts);
}
printf("\nEnter Time Slice: ");
scanf("%d",&slice);
for(i=0;i<n+1;i++)
{
if(i==0)
p[i].ts2=n*slice;
else
p[i].ts2=p[i-1].ts2+(p[i-1].ts-slice);
if(i<n)
p[i].st=i*slice;
if(i>=1)
p[i-1].ft=p[i].ts2;
}
for(i=0;i<n;i++)
p[i].wait=(i*slice-p[i].at)+(p[i].ts2-(i+1)*slice);
for(i=0;i<n;i++)
{
p[i].ta=p[i].ft-p[i].at;
p[i].nta=(float)p[i].ta/p[i].ts;
tamean=tamean+p[i].ta;

ntamean=ntamean+p[i].nta;
}
tamean=(float)tamean/n;
ntamean=(float)ntamean/n;
printf("\n Process AT ST StT FT WT TA NTA\n");
for(i=0;i<n;i++)
{
printf("Process-%c%9d%9d%12d%12d%10d%6d
%10.4f",65+i,p[i].at,p[i].ts,p[i].st,p[i].ft,p[i].wait,p[i].ta,p[i].nta);
printf("\n");
}
printf("\nturn around mean is : %f",tamean);
printf("\nnorm.turn around mean is : %f",ntamean);
getch();
}
Output:
Enter Number of Processes:: 3
Enter Arrival Time for Process -A : 0
Enter Service Time for process-A : 5
Enter Arrival Time for Process -B : 3
Enter Service Time for process-B : 7
Enter Arrival Time for Process -C : 5
Enter Service Time for process-C : 9
Enter Time Slice: 4
Process
Process-A
Process-B
Process-C

AT
0
3
5

ST

StT

5
7
9

0
4
8

FT
13
16
21

turn around mean is : 14.000000


norm.turn around mean is : 2.078307

WT

TA
8
6
7

NTA
13
13
16

2.6000
1.8571
1.7778

2. Loading executable programs into memory and execute system call implementation read(),write(),
open() and close()
PROGRAM :
#include <stdio.h>
#include <fcntl.h>
#include "syscalls.h"
#define PERMS 0666

/* RW for owner, group, others */

void error(char *, ...);


/* cp: copy f1 to f2 */
main(int argc, char *argv[])
{
int f1, f2, n;
char buf[BUFSIZ];
if (argc != 3)
error("Usage: cp from to");
if ((f1 = open(argv[1], O_RDONLY, 0)) == -1)
error("cp: can't open %s", argv[1]);
if ((f2 = creat(argv[2], PERMS)) == -1)
error("cp: can't create %s, mode %03o",
argv[2], PERMS);
while ((n = read(f1, buf, BUFSIZ)) > 0)
if (write(f2, buf, n) != n)
error("cp: write error on file %s", argv[2]);
return 0;
}

3. Multiprogramming-Memory management implementation of fork(),wait(),exec() & exit() system calls

The fork() System Call


System call fork() is used to create processes. It takes no arguments and returns a process ID. The
purpose of fork() is to create a new process, which becomes the child process of the caller. After a new
child process is created, both processes will execute the next instruction following the fork() system call.
Therefore, we have to distinguish the parent from the child. This can be done by testing the returned value
of fork():

If fork() returns a negative value, the creation of a child process was unsuccessful.

fork() returns a zero to the newly created child process.

fork() returns a positive value, the process ID of the child process, to the parent. The returned
process ID is of type pid_t defined in sys/types.h. Normally, the process ID is an integer.
Moreover, a process can use function getpid() to retrieve the process ID assigned to this process.

Therefore, after the system call to fork(), a simple test can tell which process is the child.
PROGRAM :
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#define MAX_COUNT 200
#define BUF_SIZE 100
void main(void)
{
pid_t pid;
int i;
char buf[BUF_SIZE];
fork();
pid = getpid();
for (i = 1; i <= MAX_COUNT; i++) {
sprintf(buf, "This line is from pid %d, value = %d\n", pid, i);
write(1, buf, strlen(buf));
}
}
Suppose the above program executes up to the point of the call to fork() (marked in red color):

If the call to fork() is executed successfully, Unix will

make two identical copies of address spaces, one for the parent and the other for the child.

Both processes will start their execution at the next statement following the fork() call. In this
case, both processes will start their execution at the assignment statement as shown below:

Both processes start their execution right after the system call fork(). Since both processes have
identical but separate address spaces, those variables initializedbefore the fork() call have the same
values in both address spaces. Since every process has its own address space, any modifications will be
independent of the others. In other words, if the parent changes the value of its variable, the modification
will only affect the variable in the parent process's address space. Other address spaces created
by fork() calls will not be affected even though they have identical variable names.
What is the reason of using write rather than printf? It is because printf() is "buffered,"
meaning printf() will group the output of a process together. While buffering the output for the parent
process, the child may also use printf to print out some information, which will also be buffered. As a
result, since the output will not be send to screen immediately, you may not get the right order of the
expected result. Worse, the output from the two processes may be mixed in strange ways. To overcome
this problem, you may consider to use the "unbuffered" write.
If you run this program, you might see the following on the screen:

................
This line is from pid 3456, value 13
This line is from pid 3456, value 14
................
This line is from pid 3456, value 20
This line is from pid 4617, value 100
This line is from pid 4617, value 101
................
This line is from pid 3456, value 21
This line is from pid 3456, value 22
................
Process ID 3456 may be the one assigned to the parent or the child. Due to the fact that these processes
are run concurrently, their output lines are intermixed in a rather unpredictable way. Moreover, the order
of these lines are determined by the CPU scheduler. Hence, if you run this program again, you may get a
totally different result.
Consider one more simple example, which distinguishes the parent from the child.
#include <stdio.h>
#include <sys/types.h>
#define MAX_COUNT 200
void ChildProcess(void);
void ParentProcess(void);

/* child process prototype */


/* parent process prototype */

void main(void)
{
pid_t pid;
pid = fork();
if (pid == 0)
ChildProcess();
else
ParentProcess();
}
void ChildProcess(void)
{
int i;
for (i = 1; i <= MAX_COUNT; i++)
printf(" This line is from child, value = %d\n", i);
printf(" *** Child process is done ***\n");
}
void ParentProcess(void)
{
int i;

for (i = 1; i <= MAX_COUNT; i++)


printf("This line is from parent, value = %d\n", i);
printf("*** Parent is done ***\n");
}
In this program, both processes print lines that indicate (1) whether the line is printed by the child
or by the parent process, and (2) the value of variable i. For simplicity, printf() is used.
When the main program executes fork(), an identical copy of its address space, including the
program and all data, is created. System call fork() returns the child process ID to the parent and returns 0
to the child process. The following figure shows that in both address spaces there is a variable pid. The
one in the parent receives the child's process ID 3456 and the one in the child receives 0.

Now both programs (i.e., the parent and child) will execute independent of each other starting at the next
statement:

In the parent, since pid is non-zero, it calls function ParentProcess(). On the other hand, the child has a
zero pid and calls ChildProcess() as shown below:

4. Simulate all file allocation strategies


i. Sequential
ii. Indexed
iii. Linked

I. Sequential file Allocation


PROGRAM :
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int st[20],b[20],b1[20],ch,i,j,n,blocks[20][20],sz[20];
char F[20][20],S[20];
clrscr();
printf("\n Enter no. of Files ::");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\n Enter file %d name ::",i+1);
scanf("%s",&F[i]);
printf("\n Enter file%d size(in kb)::",i+1);
scanf("%d",&sz[i]);
printf("\n Enter Starting block of %d::",i+1);
scanf("%d",&st[i]);
printf("\n Enter blocksize of File%d(in bytes)::",i+1);
scanf("%d",&b[i]);
}
for(i=0;i<n;i++)
b1[i]=(sz[i]*1024)/b[i];
for(i=0;i<n;i++)
{
for(j=0;j<b1[i];j++)
blocks[i][j]=st[i]+j;
}

do
{
printf("\nEnter the Filename ::");
scanf("%s",S);
for(i=0;i<n;i++)
{
if(strcmp(S,F[i])==0)
{
printf("\nFname\tStart\tNblocks\tBlocks\n");
printf("\n---------------------------------------------\n");
printf("\n%s\t%d\t%d\t",F[i],st[i],b1[i]);
for(j=0;j<b1[i];j++)
printf("%d->",blocks[i][j]);
}
}
printf("\n---------------------------------------------\n");
printf("\nDo U want to continue ::(Y:n)");
scanf("%d",&ch);
if(ch!=1)
break;
}while(1);
}
/*Input and Output;Enter no. of Files ::2
Enter file 1 name ::x.c
Enter file1 size(in kb)::4
Enter Starting block of 1::100
Enter blocksize of File1(in bytes)::512
Enter file 2 name ::y.c
Enter file2 size(in kb)::2
Enter Starting block of 2::500
Enter blocksize of File2(in bytes)::256
Enter the Filename ::y.c
Fname Start Nblocks Blocks
--------------------------------------------y.c 500 8
500->501->502->503->504->505->506->507->
--------------------------------------------Do U want to continue ::(Y:n) n
*/

II. Index file Allocation Method


PROGRAM :
#include<stdio.h>
#include<conio.h>
#include<string.h>
int n;
void main()
{
int b[20],b1[20],i,j,blocks[20][20],sz[20];
char F[20][20],S[20],ch;
clrscr();
printf("\n Enter no. of Files ::");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\n Enter file %d name ::",i+1);
scanf("%s",&F[i]);
printf("\n Enter file%d size(in kb)::",i+1);
scanf("%d",&sz[i]);
printf("\n Enter blocksize of File%d(in bytes)::",i+1);
scanf("%d",&b[i]);
}
for(i=0;i<n;i++)
{
b1[i]=(sz[i]*1024)/b[i];
printf("\n\nEnter blocks for file%d",i+1);
for(j=0;j<b1[i];j++)
{
printf("\n Enter the %dblock ::",j+1);
scanf("%d",&blocks[i][j]);
}
}
do
{
printf("\nEnter the Filename ::");
scanf("%s",&S);
for(i=0;i<n;i++)
{
if(strcmp(F[i],S)==0)
{

printf("\nFname\tFsize\tBsize\tNblocks\tBlocks\n");
printf("\n---------------------------------------------\n");
printf("\n%s\t%d\t%d\t%d\t",F[i],sz[i],b[i],b1[i]);
for(j=0;j<b1[i];j++)
printf("%d->",blocks[i][j]);
}
}
printf("\n---------------------------------------------\n");
printf("\nDo U want to continue ::(Y:n)");
scanf("%d",&ch);
}while(ch!=0);
}
Input and Output:
Enter no. of Files ::2
Enter file 1 name ::x.c
Enter file1 size(in kb)::1
Enter blocksize of File1(in bytes)::512
Enter file 2 name ::y.c
Enter file2 size(in kb)::1
Enter blocksize of File2(in bytes)::512
Enter blocks for file1
Enter the 1block ::1000
Enter the 2block ::1001
Enter blocks for file2
Enter the 1block ::2000
Enter the 2block ::2001
Enter the Filename ::x.c
Fname Fsize Bsize Nblocks Blocks
---------------------------------------------

x.c 1
512 2
1000->1001->
--------------------------------------------Do U want to continue ::(Y:n)1
Enter the Filename ::y.c
Fname Fsize Bsize Nblocks Blocks
--------------------------------------------y.c 1
512 2
2000->2001->
--------------------------------------------Do U want to continue ::(Y:n)0
III. Linked file Allocation Method
PROGRAM
#include<stdio.h>
#include<conio.h>
#include<string.h>
int n;
void main()
{
int b[20],b1[20],i,j,blocks[20][20],sz[20];
char F[20][20],S[20],ch;
int sb[20],eb[20],x;
clrscr();
printf("\n Enter no. of Files ::");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\n Enter file %d name ::",i+1);
scanf("%s",&F[i]);
printf("\n Enter file%d size(in kb)::",i+1);
scanf("%d",&sz[i]);
printf("\n Enter blocksize of File%d(in bytes)::",i+1);
scanf("%d",&b[i]);
}
for(i=0;i<n;i++)
{
b1[i]=(sz[i]*1024)/b[i];
printf("\n Enter Starting block of file%d::",i+1);
scanf("%d",&sb[i]);
printf("\n Enter Ending block of file%d::",i+1);

scanf("%d",&eb[i]);
printf("\nEnter blocks for file%d::\n",i+1);
for(j=0;j<b1[i]-2;)
{
printf("\n Enter the %dblock ::",j+1);
scanf("%d",&x);
if(x>sb[i]&&x<eb[i])
{
blocks[i][j]=x;
j++;
}
else
printf("\n Invalid block::");
}
}
do
{
printf("\nEnter the Filename ::");
scanf("%s",&S);
for(i=0;i<n;i++)
{
if(strcmp(F[i],S)==0)
{
printf("\nFname\tFsize\tBsize\tNblocks\tBlocks\n");
printf("\n---------------------------------------------\n");
printf("\n%s\t%d\t%d\t%d\t",F[i],sz[i],b[i],b1[i]);
printf("%d->",sb[i]);
for(j=0;j<b1[i]-2;j++)
printf("%d->",blocks[i][j]);
printf("%d->",eb[i]);
}
}
printf("\n---------------------------------------------\n");
printf("\nDo U want to continue (Y:n)::");
scanf("%d",&ch);
}while(ch!=0);
}
/*Input and Output;Enter file1 size(in kb)::1
Enter blocksize of File1(in bytes)::512
Enter file 2 name ::sudee

Enter file2 size(in kb)::1


Enter blocksize of File2(in bytes)::1024
Enter Starting block of file::1100
Enter Ending block of file::1600
Enter blocks for file1::
Enter the 1block ::102
Enter the 2block ::104
Enter Starting block of file::2200
Enter Ending block of file::2500
Enter blocks for file2::
Enter the 1block ::201
Enter the Filename ::daya
Fname Fsize Bsize Nblocks Blocks
--------------------------------------------daya 1
512 2
100->102->104->600->
--------------------------------------------Do U want to continue ::(Y:n)1
Enter the Filename ::sudee
Fname Fsize Bsize Nblocks Blocks
--------------------------------------------sudee 1
1024 1
200->201->500->
--------------------------------------------Do U want to continue ::(Y:n)0

5. Simulate the MVT and MFT.

Description:
Memory management
CPU runs program instructions only when program is in memory.
Programs do I/O sometimes IMPLY CPU wasted.
Solution : Multiprogramming
Multiple programs share the memory
One program at a time gets CPU
Simultaneous resource possession
Better performance
Multiple Programming with Fixed Number of Tasks (MFT):
IBM in their Mainframe Operating system OS/MFT implements the MFT
concept. OS/MFT uses fixed partitioning concept to load programs into main
memory.
Fixed Partitioning:
In fixed partitioning concept, RAM is divided into set of fixed partitions of equal size.
Programs having the size less than the partition size are loaded into memory
Programs having size more than the size of partition size is rejected
The program having the size less than the partition size will lead to internal
fragmentation
If all partitions are allocated and if a new program is to be loaded, the program that
leads to maximum internal fragmentation can be replaced.
Multi-programming with variable number of tasks (MVT):
IBM in their Mainframe Operating system OS/MVT implements the MVT
concept. OS/MVT uses dynamic partitioning concept to load programs into main
memory.

Dynamic Partitioning:
Initially RAM is portioned according to the size of programs to be loaded into
Memory till such time that no other program can be loaded.
The left over memory is called a hole which is too small to fit any process
When a new program is to be loaded into memory look for the partition,
which leads to least external fragmentation and load the program.
The space that is not used in a partition is called as external fragmentation

Multi-programming with variable number of tasks (MVT):

#include<stdio.h>
#include<conio.h>
main()
{
static int jobs[20][20],flag[10];
int ch;
static int i,k,nj,nb,tms;
clrscr();
printf("Enter time"); /* reading time */
scanf("%d",&tms);
printf("Enter no. of jobs"); /* reading no of jobs */
scanf("%d",&nj);
printf("Enter job information 1.jobid 2.jobsize");
for(i=0;i<nj;i++)
scanf("%d%d",&jobs[i][0],&jobs[i][1]);
for(i=0;i<nj;i++)
{
if(tms>=jobs[i][1])
{
tms=tms-jobs[i][1];
nb=nb+1;
flag[i]=1;
}
}
printf("Total memory space available which is not allocated is:%d\n",tms);
printf("Jobs which are not allocated:");
for(i=0;i<nj;i++)
if(flag[i] == 0)
printf("%d\t%d\n",jobs[i][0],jobs[i][1]);
if(nb!=nj)
{
while(1)
{
printf("enter jobid to deallocate:");
scanf("%d",&k);
for(i=0;i<nj;i++)
{
if(jobs[i][0] == k)
{

if(flag[i] ==1)
{
tms=tms+jobs[i][1];
flag[i]=2;
printf("Deallocated job %d\t%d\n", jobs[i][0],jobs[i][1]);
}
}
}
for(i=0;i<nj;i++)
{
if (tms>=jobs[i][1])
{
if(flag[i] == 0)
{
tms=tms-jobs[i][1];
flag[i]=1;
}
}
}
printf("Remaining memory is: %d",tms);
printf("Jobs which are not allocated are:");
for( i=0;i<nj;i++)
/* dellocating mamory*/
if(flag[i] ==0)
printf("%d\t%d\n", jobs[i][0],jobs[i][1]);
printf("Do you want to deallocate 1.Yes 2.No");
scanf("%d",&ch);
if(ch ==2)
break;
}
}
printf("Allocated jobs are:");
for(i=0;i<nj;i++)
if(flag[i]==1)
printf("%d\t%d\n",jobs[i][0],jobs[i][1]);
getch();
}

Output:
Enter time: 100
Enter no. of jobs: 5
Enter job information 1.jobid 2.jobsize

1
2
3
4
5

20
25
15
30
15
Total memory space available which is not allocated is: 10
Jobs which are not allocated: 5 15
Enter jobid to deallocate: 1
Deallocated job: 1 20
Remaining memory is: 15
Jobs which are not allocated are:
Do you want to deallocate 1.Yes 2.No : 1
Enter jobid to deallocate: 4
Deallocated job: 4 30
Remaining memory is 45
Jobs which are not allocated are:
Do you want to deallocate 1.Yes 2.No : 2
Allocated jobs are
2
25
3
15
5
15

Multiple Programming with Fixed Number of Tasks (MFT):


#include<stdio.h>
#include<conio.h>
void main()
{
int tms,element,nb,i,j,t,index,frag,ch,count=0;

static int jobs[20][20],sz[20][20],nj,s;


clrscr();
printf("enter total memory space"); /* reading memory */
scanf("%d",&tms); /* reading choices */
printf("enter choice\n1.equal partition 2.unequal partition\n");
scanf("%d",&ch);
if(ch==1)
{
printf("enter size of each block");
scanf("%d",&s);
nb=tms/s;
for(i=0;i<nb;i++)
scanf("%d",&sz[i][0]);
}
else
{
printf("enter no. of blocks");
scanf("%d",&nb);
printf("enter size of %d blocks");
for(i=0;i<nb;i++)
scanf("%d",sz[i][0]);
}
printf("enter no. of jobs"); /* reading no of jobs */
scanf("%d",&nj);
printf("enter job information 1.jobid 2.job size\n");
for(i=0;i<nj;i++)
scanf("%d%d",&jobs[i][0],&jobs[i][1]);
frag=0;
for(j=0;j<nj;j++)
{
if(sz[j][0]>=element && sz[i][0]<=t)
{
if(sz[j][1]!=1)
{
t=sz[j][0];
index=j;
}
}
}

if(sz[index][1]!=1)
{
sz[index][1]=1;

jobs[i][2]=2;
frag=frag+(t-element);
count++;
}
printf("total internal fragmentation : %d", frag);
printf("no. of free blocks: %d" , nb-count);
printf("the jobs which are not allocated");
if(count==nj)
printf(" 0");
for(i=0;i<nj;i++)
{
if(jobs[i][2]!=2)
printf("jobid ------%d\tjob size-----%d\n",jobs[i][0],jobs[i][1]);
}
getch();
}

Output:
Enter total memory space: 100
enter choice 1. equal partition 2. unequal partition 2
enter no. of blocks: 3
enter size of 3 blocks: 50 25 25
enter no. of jobs 4
enter job information 1.jodid 2. jobsize
1 25
2 30
3 26
4 20
5 25
total internal fragmentation : 9
no. of free blocks : 0
the jobs which are not allocated :
job id----4 jobsize----20
jobid----5
jobsize----25

6. Simulate all File Organization Techniques


a. Single level directory
b.Two level

Description:
Higher level file organization techniques such as ISAM (Indexed Sequential Access Method) or
VSAM (Virtual System Access Method) could incur large seek times because of a double of triple access
to retrieve one record (index(s) and data).
Disk optimization is critical in these cases, but is more complex, because data retrieved from one
disk (the index) indicates where the next seek is (data which that index points to). Data and index
portions of data sets are not normally stored next to each other, and sometimes are stored on different
packs.
What might be the impact of placing the index on one pack and the data on another?
Major concepts:

Files are made up of records; records are made up of fields


Disk blocks are smaller than files and larger than records; files must be split into disk blocks for
storage (and the records in a file must be grouped somehow for storage on disk blocks, independent of the
file organization)
Fixed-length records
Variable length records
Block structure: fixed-packed or slotted page
File structure: heap, sequential, hashed, or clustered
Details of the above file structures
Files are logical units mapped onto physical secondary storage
File name: logical object
Physical objects: blocks on disk, tape, optical disk
One or more sectors: smallest unit to read from or write to disk
Block: unit of I/o transfer from disk to memory
Secondary storage: nonvolatile
File attributes: frequency of additions and deletions
Activity: percentage of records accessed during time frame
Directory : keep track of files
Create the illusion of compartments

Single Level Directory


#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<graphics.h>
void main()
{
int gd=DETECT,gm,count,i,j,mid,cir_x;
char fname[10][20];
clrscr();
initgraph(&gd,&gm,"c:/tc/bgi");

cleardevice();
setbkcolor(GREEN);
printf("enter number of files");
scanf("&d",&count);
if(i<count)
// for(i=0;i<count;i++)
{
cleardevice();
setbkcolor(GREEN);
printf("enter %d file name:",i+1);
scanf("%s",fname[i]);
setfillstyle(1,MAGENTA);
mid=640/count;
cir_x=mid/3;
bar3d(270,100,370,150,0,0);
settextstyle(2,0,4);
settextjustify(1,1);
outtextxy(320,125,"root directory");
setcolor(BLUE);
i++;
for(j=0;j<=i;j++,cir_x+=mid)
{
line(320,150,cir_x,250);
fillellipse(cir_x,250,30,30);
outtextxy(cir_x,250,fname[i]);
}
}
getch();
}

Two Level Directory:


#include<stdio.h>
#include<graphics.h>
struct tree_element
{
char name[20];
int x,y,ftype,lx,rx,nc,level;
struct tree_element *link[5];
};
typedef struct tree_element node;
void main()

{
int gd=DETECT,gm;
node *root;
root=NULL;
clrscr();
create(&root,0,"null",0,639,320);
clrscr();
initgraph(&gd,&gm,"c:\tc\bgi");
display(root);
getch();
closegraph();
}
create(node **root,int lev ,char *dname,int lx,int rx,int x)
{
int i, gap;
if(*root==NULL)
{
(*root)=(node*)malloc(sizeof(node));
printf("enter the name of ir file name %s",dname);
fflush(stdin);
gets((*root)->name);
if(lev==0 || lev==1)
(*root)-> ftype=1;
else
(*root)->ftype=2;
(*root)->level=lev;
(*root)->y=50+lev*50;
(*root)->x=x;
(*root)->lx=lx ;
(*root)->rx=rx;
for(i=0;i<5;i++)
(*root)->link[i]=NULL;
if((*root)->ftype==1)
{
if(lev==0 || lev==1)
{
if((*root)->level==0)
printf("how many users");
else
printf(" how many files");
printf("(for %s):",(*root)->name);
scanf("%d",&(*root)->nc);
}
else

(*root)->nc=0;
if((*root)->nc==0)
gap=rx-lx;
else
gap=(rx-lx)/(*root)->nc;
for(i=0;i<(*root)->nc;i++)
create(&((*root)->link[i]),lev+1,(*root)>name,lx+gap*i,lx+gap*i+gap,lx+gap*i+gap/2);
}
else
(*root)->nc=0;
}
}
display(node *root)
{
int i;
settextstyle(2,0,4);
settextjustify(1,1);
setfillstyle(1,BLUE);
setcolor(14);
if(root!=NULL)
{
for(i=0;i<root->nc;i++)
{
line(root->x,root->y,root->link[i]->x,root->link[i]->y);
}
if(root->ftype==1)
bar3d(root->x-20, root->y-10,root->x+20,root->y+10,0,0);
else
fillellipse(root->x,root->y,20,20);
outtextxy(root->x,root->y,root->name);
for(i=0;i<root->nc;i++)
{
display(root->link[i]);
}
}
}

7. Simulate Bankers algorithm for deadlock avoidance


Aim: To simulate bankers algorithm for deadlock avoidance
Description:
Deadlock Definition
A set of processes is deadlocked if each process in the set is waiting for an event that only another
process in the set can cause (including itself).

Waiting for an event could be:

waiting for access to a critical section


waiting for a resource Note that it is usually a non-preemptable (resource). Preemptable
resources can be yanked away and given to another.

Conditions for Deadlock


Mutual exclusion: resources cannot be shared.
Hold and wait: processes request resources incrementally, and hold on to what they've got.
No preemption : resources cannot be forcibly taken from processes.
Circular wait: circular chain of waiting, in which each process is waiting for a resource held by
the next process in the chain.
Strategies for dealing with Deadlock
ignore the problem altogether
detection and recovery
avoidance by careful resource allocation
prevention by structurally negating one of the four necessary conditions.
Deadlock Avoidance
Avoid actions that may lead to a deadlock. Think of it as a state machine moving from one state
to another as each instruction is executed.

Safe State
Safe state is one where

It is not a deadlocked state

BANKERS ALGORITHM FOR DEADLOCK AVOIDANCE


#include<stdio.h>
#include<conio.h>
main()
{
int a[10][10],c[10][10],r[10],av[10],ca[10][10],i,j,k,n,m,temp=0,tem,ch;
clrscr();

printf("enter no processes");
scanf("%d",&m);
printf("enter no of resources");
scanf("%d",&n);
printf("\nenter claim\n");
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&c[i][j]);
printf("\nenter alocation matrix\n");
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
printf("\nenter resourse vector\n");
for(i=0;i<n;i++)
scanf("%d",&r[i]);
k=0;
do
{
printf("claim\tallocation\tca\n");
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
printf("%3d",c[i][j]);printf("\t");
for(j=0;j<n;j++)
printf("%3d",a[i][j]);printf("\t\t");
for(j=0;j<n;j++)
{
ca[i][j]=c[i][j]-a[i][j];
printf("%3d",ca[i][j]);
}
printf("\n");
}
temp=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
temp=temp+a[j][i];
av[i]=r[i]-temp;temp=0;
}
printf("\nresource vector: ");
for(i=0;i<n;i++)
printf("%3d",r[i]);
printf("\navailable vector: ");
for(i=0;i<n;i++)

printf("%3d",av[i]);
if(k==0)
printf("\n****initial state****\n");
else
printf("\n***p%d runs to completion*****\n",tem+1);
if(k<n)
{
temp=0;
for(i=0;i<m;i++)
{
lab:for(j=0;j<n;j++)
{
if(ca[i][j]==0)
temp++;
}
if(temp==n)
{
i++; temp=0;goto lab;
}
else
{
for(j=0;j<n;j++)
{
if(ca[i][j]<=av[j])
tem=i;
else
{
if(i>m)
{
printf("\nunshafe state");goto end;
}
else
{i++;goto lab;}
}
}
}
for(j=0;j<n;j++)
{
a[tem][j]=0;c[tem][j]=0;ca[tem][j]=0;
}
break;
}
}
else

{
printf("\nprocesses are completed");
goto end;
}
k++;
printf("continue press ZERO");
scanf("%d",&ch);
}while(ch==0);
end: getch();
}

Output:
enter no processes 3
enter no of resources 3
enter claim
322
613
314
enter allocation matrix
100
612
211
enter resource vector
936
claim
allocation
3 2 2
1 0 0
6 1 3
6 1 2
3 1 4
2 1 1
resource vector: 9 3 6
available vector: 0 1 3
****initial state****
continue press ZERO 0
enter allocation matrix
100
612
211
enter resource vector
936

ca
2 2 2
0 0 1
1 0 3

claim
allocation
ca
3 2 2
1 0 0
2 2 2
6 1 3
6 1 2
0 0 1
3 1 4
2 1 1
1 0 3
resource vector: 9 3 6
available vector: 0 1 3
****initial state****
continue press ZERO 0
claim
allocation
ca
3 2 2
1 0 0
2 2 2
0 0 0
0 0 0
0 0 0
3 1 4
2 1 1
1 0 3
resource vector: 9 3 6
available vector: 6 2 5
***p2 runs to completion*****
continue press ZERO 0
claim
allocation ca
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
3 1 4
2 1 1
1 0 3
resource vector: 9 3 6
available vector: 7 2 5
***p1 runs to completion*****
continue press ZERO0
claim allocation ca
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
resource vector: 9 3 6
available vector: 9 3 6
***p3 runs to completion*****
processes are completed
8. Simulate Bankers Algorithm for Deadlock prevention
Aim: To simulate Bankers Algorithm for Deadlock Prevention
Description:

Deadlock Prevention
Difference from avoidance is that here, the system itself is built in such a way that there are no
deadlocks.
Make sure atleast one of the 4 deadlock conditions is never satisfied. This may however be even
more conservative than deadlock avoidance strategy.

o
o

Attacking Mutex condition


never grant exclusive access. but this may not be possible for several resources.
Attacking preemption
not something you want to do.
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

o
o

Attacking circular wait


Order all the resources.
Make sure that the requests are issued in the correct order so that there are no cycles
present in the resource graph.
Resources numbered 1 ... n. Resources can be requested only in increasing order. ie. you cannot request a
resource whose no is less than any you may be holding.

PROGRAM
#include<stdio.h>
#include<conio.h>
int max[10][10],alloc[10][10],need[10][10],avail[10],i,j,p,r,finish[10]={0},flag=0;
main( )
{
clrscr( );
printf("\n\nSIMULATION OF DEADLOCK PREVENTION");
printf("Enter no. of processes, resources");
scanf("%d%d",&p,&r);
printf("Enter allocation matrix");
for(i=0;i<p;i++)
for(j=0;j<r;j++)
scanf("%d",&alloc[i][j]);
printf("enter max matrix");
for(i=0;i<p;i++)
/*reading the maximum matrix and availale matrix*/
for(j=0;j<r;j++)
scanf("%d",&max[i][j]);
printf("enter available matrix");

for(i=0;i<r;i++)
scanf("%d",&avail[i]);
for(i=0;i<p;i++)
for(j=0;j<r;j++)
need[i][j]=max[i][j]-alloc[i][j];
fun();
/*calling function*/
if(flag==0)
{
if(finish[i]!=1)
{
printf("\n\n Failing :Mutual exclusion");
for(j=0;j<r;j++)
{ /*checking for mutual exclusion*/
if(avail[j]<need[i][j])
avail[j]=need[i][j];
}
fun();
printf("\n By allocating required resources to process %d dead lock is prevented ",i);
printf("\n\n lack of preemption");
for(j=0;j<r;j++)
{
if(avail[j]<need[i][j])
avail[j]=need[i][j];
alloc[i][j]=0;
}
fun( );
printf("\n\n daed lock is prevented by allocating needed resources");
printf(" \n \n failing:Hold and Wait condition ");
for(j=0;j<r;j++)
{
/*checking hold and wait condition*/
if(avail[j]<need[i][j])
avail[j]=need[i][j];
}
fun( );
printf("\n AVOIDING ANY ONE OF THE CONDITION, U CAN PREVENT DEADLOCK");
}
}
getch( );
}
fun( )
{
while(1)
{
for(flag=0,i=0;i<p;i++)

{
if(finish[i]==0)
{
for(j=0;j<r;j++)
{
if(need[i][j]<=avail[j])
continue;
else
break;
}
if(j==r)
{
for(j=0;j<r;j++)
avail[j]+=alloc[i][j];
flag=1;
finish[i]=1;
}
}
}
if(flag==0)
break;
}
}

Output:
SIMULATION OF DEADLOCK PREVENTION
Enter no. of processes, resources 3, 2
enter allocation matrix 2 4 5
4 5
Enter max matrix4 3 4
5 6 1
Enter available matrix2
5
Failing : Mutual Exclusion
by allocating required resources to process dead is prevented
Lack of no preemption
deadlock is prevented by allocating needed resources
Failing : Hold and Wait condition
BY AVOIDING ONE OF THE ABOVE CONDITION, YOU CAN PREVENT DEADLOCK

9. Simulate all Page Replacement Algorithms


a) FIFO
b) LRU
c) LFU
a) FIFO:
AIM: A program to simulate FIFO Page Replacement Algorithm
Description:
FIFO
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 earliest arrival
in front.
When a page needs to be replaced, the page at the front of the queue (the
oldest page) is selected. While FIFO is cheap and intuitive, it performs poorly in
practical application. Thus, it is rarely used in its unmodified form. This algorithm
experiences Belady's anomaly.
Least Recently Used (LRU)
The least recently used page (LRU) replacement algorithm 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. While LRU can provide
near-optimal performance in theory it is rather expensive to implement in practice.
There are a few implementation methods for this algorithm that try to reduce the
cost yet keep as much of the performance as possible.

The most expensive method is the linked list method, which uses a linked list
containing all the pages in memory. At the back of this list is the least recently used
page, and at the front is the most recently used page. The cost of this
implementation lies in the fact that items in the list will have to be moved about
every memory reference, which is a very time-consuming process.

Another method that requires hardware support is as follows: suppose the


hardware has a 64-bit counter that is incremented at every instruction. Whenever a

page is accessed, it gains a value equal to the counter at the time of page access.
Whenever a page needs to be replaced, the operating system selects the page with
the lowest counter

and swaps it out. With present hardware, this is not feasible because the required
hardware counters do not exist.

One important advantage of LRU algorithm is that it is amenable to full


statistical analysis. It has been proved, for example, that LRU can never result in
more than N-times more page faults than OPT algorithm, where N is proportional to
the number of pages in the managed pool.
On the other hand, LRU's weakness is that its performance tends to
degenerate under many quite common reference patterns. For example, if there are
N pages in the LRU pool, an application executing a loop over array of N + 1 pages
will cause a page fault on each and every access. As loops over large arrays are
common, much effort has been put into modifying LRU to work better in such
situations.

FIFO PAGE REPLACEMENT ALGORITHM


#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char prs[40],fp[10],ps;
int fs,i,j,k=0,flg1,flg2,x=5,y,pfc=0;
clrscr();
printf("\n enter page reference string:");
gets(prs);
printf("\n enter the frame size:");
scanf("%d",&fs);
for(i=0;i<fs;i++)
fp[i]='x';
clrscr();
printf("\n page replacement technique :: FIFO algorithm:");
printf("\n .............................................");

printf("\n F-Page Fault \t H- Page Hit \n");


for(i=0;i<strlen(prs);i++,x+=2)
{
flg1=0;
ps='F';
for(j=0;j<fs;j++)
if(fp[j]==prs[i]){
ps='H';
flg1=1;
break;
}
if(flg1==0)
{
flg2=0;
for(j=0;j<fs;j++)
if(fp[j]=='x')
{
fp[j]=prs[i];
pfc++;
flg2=1;
break;
}
if(flg2==0)
{
pfc++;
fp[k]=prs[i];
k++;
if(k==fs)
k=0; }
}
y=5;
gotoxy(x,y);
printf("%c",prs[i]);
y++;
gotoxy(x,y);
printf("--");
y++;
for(j=0;j<fs;y++,j++)
{
gotoxy(x,y);
printf("%c",fp[j]);
}
y++;
gotoxy(x,y);
printf("--");

y++;
gotoxy(x,y);
printf("%c",ps);
}
printf("\n \n\n\n\n Total page Faults=%d",pfc);
getch();
}

OUTPUT
enter page reference string :
232152453252
enter the frame size:
3
page replacement technique:: FIFO algorithm
................................................................................
F-page fault H-page hit
2 3 2 1 5 2 4 5 3 2 5 2
---------------------------2 2 2 2 5 5 5 5 3 3 3 3
x 3 3 3 3 2 2 2 2 2 5 5
x x x 1 1 1 4 4 4 4 4 2
--------------------------F FHFF F F H F H F F
total page faults=9

LFU PAGE REPLACEMENT ALGORITHM


#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char prs[40],fp[10],ps;
int fs,i,j,k,flg1,flg2,x=5,y,pfc=0,ru[10],min;
clrscr();
printf("\n ENTER THE PAGE REFERENCE STRING:");
gets(prs);
printf("\n enter the frame size:");

scanf("%d",&fs);
for(i=0;i<fs;i++)
{
fp[i]='X';
ru[i]=0;
}
clrscr();
printf("\n PAGE REPLACEMENT TECHNIQUE ::LFU ALGORITHM \n");
printf("\n .......................................... \n");
printf("F-Page Fault \t H-Page Hit\n");
for(i=0;i<strlen(prs);i++,x+=5)
{
flg1=0;
ps='F';
for(j=0;j<fs;j++)
{
if(fp[j]==prs[i])
{
ps='H';
(ru[j])++;
flg1=1;
break;
}
}
if(flg1==0)
{
pfc++;
flg2=0;

for(j=0;j<fs;j++)
{
if(fp[j]=='X')
{
fp[j]=prs[i];
ru[j]=1;
flg2=1;
break;
}
}
if(flg2==0)
{

min=0;
for(j=1;j<fs;j++)
{
if(ru[min]>=ru[j])
{
if(ru[min]>ru[j])
min=j;
else
{
for(k=0;k<i;k++)
{
if(prs[k]==fp[min])
break;
if(prs[k]==fp[j])
{
min=j;
break;
}}}}}
fp[min]=prs[i];
ru[min]=1;
}
}
y=5;
gotoxy(x,y);
printf("%c",prs[i]);
y++;
gotoxy(x,y);
printf("-----");
y++;
for(j=0;j<fs;y++,j++)
{
gotoxy(x,y);
printf("%c(%d)",fp[j],ru[j]);
}

y++;
gotoxy(x,y);
printf("-----");
y++;
gotoxy(x,y);
printf("%c",ps);
}

printf("\n\n\n\n\n TOTAL PAGE FAULTS =%d",pfc);


getch();
}

OUTPUT :
enter the page referrence string :232152453252
enter frame size :3

2
3
2
1
5
2
4
5
3
2
5
2
----------------------------------------------------------------------------------------------------2(1)
2(1)
2(2)
2(2)
2(2)
2(3) 2(3) 2(3) 2(3) 2(4) 2(4) 2(5)
X(0)
3(1)
3(1)
3(1)
5(1)
5(1) 5(2) 5(2) 5(2) 5(2) 5(3) 5(3)
X(0)
X(0)
X(0) 1(1)
1(1)
1(1) 4(1) 4(1) 3(1) 3(1)
3(1) 3(1)
----------------------------------------------------------------------------------------------------F
F
H
F
F
H
F
H
F
H
H
H
TOTAL PAGE FAULTS = 6

LRU PAGE REPLACEMENT ALGORITHM


#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char prs[40],fp[10],ps;
int fs,i,j,k,flg1,flg2,x=5,y,pfc=0,ru[10],min;
clrscr();
printf("enter the page reference string:");
gets(prs);
printf("enter the frame size:");
scanf("%d",&fs);
for(i=0;i<fs;i++)
{
fp[i]='x';

ru[i]=0;
}
clrscr();
printf("PAGE REPLACEMENT TECHNIQUE::LRU algorithm\n");
printf("-----------------------------------\n");
printf("F-Page fault\tH-Page Hit\n");
for(i=0;i<strlen(prs);i++,x+=2)
{
flg1=0;
ps='F';
for(j=0;j<fs;j++)
{
if(fp[j]==prs[i])
{
ps='H';
ru[j]=i;
flg1=1;
break;
}
}
if(flg1==0)
{
pfc++;
flg2=0;
for(j=0;j<fs;j++)
{
if(fp[j]=='X')
{
fp[j]=prs[i];
ru[j]=i;
flg2=1;
break;
}
}
if(flg2==0)
{
min=0;
for(j=1;j<fs;j++)
{
if(ru[min]>ru[j])
min=j;
}
fp[min]=prs[i];
ru[min]=i;
}
}
y=5;

gotoxy(x,y);
printf("%c",prs[i]);
y++;
gotoxy(x,y);
printf("- -");
y++;
for(j=0;j<fs;y++,j++)
{
gotoxy(x,y);
printf("%c",fp[j]);
}
y++;
gotoxy(x,y);
printf("--");
y++;
gotoxy(x,y);
printf("%c",ps);
}
printf("\n\n\n\n\n\n total page faults=%d",pfc);
getch();
}
OUTPUT:
enter the page referrence string :232152453252
enter frame size :3
2 3 2 1 5 2 4 5 3 2 5 2
--------------------------------------------2 3 3 3 5 5 5 5 5 5 5 5
X X 2 2 2 2 2 2 3 3 3 3
X X X 1 1 1 4 4 4 2 2 2
--------------------------------------------F F F F F H F H F F H H
TOTAL NO OFPAGE FAULTS=8

10.Simulate Paging Technique of memory management.


Aim: Simulate Paging Technique of memory management.
Description:

Goal: eliminate external fragmentation


Each process is a set of fixed size pages
Pages are stored in same size physical memory frame
Page table connects logical pages with physical frames
May still have internal fragmentation
Logical Address: page(p) and displacement/offset (d) in page
Physical address: frame (f) and displacement/offset (d) in frame
PTBR: page table base register
PTLR: page table length register
Byte g: logical address =
Page size: 2**n
Logical address space : 2**m
Page number: high-order m-n bits
Page offset: low-order n bits
Page fault details:
Trap to OS save user registers and process table
Determine that interrupt was a page fault check page reference and location in disk
Issue read from the disk to a free frame
Wait in queue for device
Wait for seek and /or latency
Begin transfer
While waiting, allocate CPU to other user
Interrupt from the disk
Save registers and process state of other user
Determine that interrupt was from disk
Correct page table

Wait for CPU to be allocated to this process again


Restore user registers, process state, new page table
RESUME execution

PROGRAM
#include<stdio.h>
#include<conio.h>
#include<math.h>
main()
{
int size,m,n,pgno,pagetable[3]={5,6,7},i,j,frameno;
double m1;
int ra=0,ofs;
clrscr();
printf("Enter process size (in KB of max 12KB):");/*reading memeory size*/
scanf("%d",&size);
m1=size/4;
n=ceil(m1);
printf("Total No. of pages: %d",n);
printf("\nEnter relative address (in hexadecimal notation eg.0XRA) \n");
//printf("The length of relative Address is : 16 bits \n\n The size of offset is :12 bits\n");
scanf("%d",&ra);
pgno=ra/1000;
/*calculating physical address*/
ofs=ra%1000;
printf("page no=%d\n",pgno);
printf("page table");
for(i=0;i<n;i++)
printf("\n %d [%d]",i,pagetable[i]);
frameno=pagetable[pgno];
printf("\n Equivalent physical address : %d%d",frameno,ofs);
getch();

Output:
Enter process size(in KB of max 12KB) : 12
Total no. of pages : 3
Enter relative address (in hexadecimal notation eg.0XRA): 2643

1
2
3

Page no=2
Page table
[5]
[6]
[7]
Equivalent physical address: 7643

You might also like