Finalll Os File
Finalll Os File
int flag = 0;
for(i=0;i<3;i++) {
flag-0;
for(j=0;j<100:j++){
if(disk[j] ==-1) {
for(k=j:k< j+fli].count && disk[k] ==-1;k++) {
flag++;
printf("n flag for file %d:%dn", i, flag);
if(flag == fil.count) {
for(k=j:k< j+f[i].count;k++) {
fli].start =j:
disk[k<=f[i].id;
j=i+f[i].count;
break;
else {
j=j+flag:
flag-0;
Output:
here is the disk allocation details
0000011122-1I -1 -1-1 -1 -1-1 -1 - -1-1 -1-1 -1 -1 -1-1 -1 -1-1 -1 -1 -1-1 -1 -1 -1 -1 -1 -1 -
1-1 -1-1 -1-1 -1-1 -1 -1-1 -1-1 -1-1 -1-1 -1 -1-1 -1-1 -1-1 -1 -1 -1 -1 -1 -1-1 -1-1 -1 -1 -1 -1 -1
-1 -1-1 -1 -1-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
2. Linked List
About Linked List Allocation technique:
In this scheme, each file is a linked list of disk blocks which need not be contiguous. The disk blocks
can be scattered anywhere on the disk.
The directory entry contains a pointer to the starting and the ending file block. Each block contains a
pointer to the next block occupied by the file.
The file jeep' in following image shows how the blocks are randomly distributed. The last block (25)
contains -lindicating a null pointer and does not point to any other block.
Directory
else{
temp=filel;
while (temp->next_block != NULL)
temp=temp->next_block;
temp2=(f*)malloc(sizeof(f);
temp2->id=i:
temp2->block=j:
temp2->next_block=NULL;
temp->next_block = temp2;
printf("%od\t", i);
return 0:}
Input:
Output:
Here is the disk allocation for file:
file id: 1 block number: 0 block address 38287408
file id: 1 block number: 1 block address 38287440
file id: 1 block number: 2 block address 38287472
file id: 1 block number: 3 block address 38287504
file id: 1 block number: 4 block address 38287536
file id: 1 block number: 5 block address 38287568
3. Indirect Allocation
About Indirect allocation (indexing) technique:
In this scheme, a special block known as the Index block contains the pointers to all the blocks occupied
by a file. Each file has its own index block. The ith entry in the index block contains the disk address of
the ith file block. The directory entry contains the address of the index block as shown in the image:
Directory
else{
temp=files[i]:
while ( temp->next_block != NULL)
temp=temp->next_block;
temp2=(f*)malloc(sizeof(f);
temp2->id=i;
temp2->block=j:
temp2->next_block=NULL;
temp->next_block = temp2;
printf("od\t", i);
temp=files[id):
while(temp!=NULL){
printf("file id: %dlt block number: %dt block address %d\n", temp->id, temp
>block,(int)temp);
temp=temp->next_block;
return 0:;
}
Input: Program 4(ii):
Theory -
1. Worst Fit
Worst Fit Allocate the process to the partition which is the largest sufficient among the freely available
partitions available in the main memory.
Algorithm
Step 1. Input the total number of blocks and their size.
Step 2. Input the total number of processes and their size.
Step 3. For each process in list
Find free block having max size and greater than process size
Allocate block to process
for(i=0;i<nb-1;i++){
for(j=i+1:j<nb:j++){
if(bls[i].size > bls[i].size){
temp.bid = bls[i].bid:
temp.size = blslj].size:
temp.index = bls[j].index;
bls[j].bid=bls[i].bid;
bls[j].size = bls[i].size;
bls[j].index = bls[i].index;
bls[i].bid=temp.bid;
bls[i].size = temp.size;
bls[i].index = temp.index;
}}
for(i=0;i<np;i++){
if(i >= nb ||bls[i].size <ps{i].size)
printf("\n no block is available for the process \n"):
else
ps[i].b=bls[i]:
Output:
now process block allocation list is
process id: 0 process size 3 block id 2 free space 5
process id: 1process size 2 block id 0 free space 3
process id: 2 process size 4 block id 1 free space 0
2. Best-Fit
Best Fit Allocate the process to the partition which is the first smallest sufficient partition among the
free available partition.
Algorithm
Step 1. Input the total number of blocksand their size.
Step 2. Input the total number of processes and their size.
Step 3. For each process in list
Find free block where, block size - process size = minimum
Allocate block to process
Example program for implementation of contiguous allocation techniques: Best-Fit
#include<stdio.h>
#include<stdlib.h>
int disk[20]:
struct blocks{
int bid;
int size;
int index;
}block;
struct processs{
int pid;
int size:
int flag;
struct blocks b;
int fragmnent;
}process;
int main(){
int nb, np, i,j:
int disk_index=0;
printf(" Total disk size is 20 \n'");
printf(" enter numebr of blocks: "):
scanf("%od", &nb):
struct blocks bls[nb]:
for(i=0;i<nb;i++){
bls[i].bid=i;
printf("enter the size of block %d", i):
scanf("%d", &bls[il.size);
bls[i].index=disk_index;
disk_index=disk_index+bls[i].size;
pslpindex].b = bls[i):
ps[pindex].flag = 1;
temp2=20;
Output:
now process block allocation list is
process id: 0 process size 3 block id 1 free space 1
process id: 1 process size 2 block id 3 free space l
process id: 2 process size 4 block id 0 free space 1
3. First Fit
First Fit: In the first fit, the partition is allocated which is first sufficient block from the top of Main
Memory.
Algorithm
Step 1. Input the total number of blocks and their size.
Step 2. Input the total number of processes and their size.
Step 3. For each process in list
Find free block where, block size > process _size
Allocate block to process
Example program for implementation of contiguous allocation techniques: First-Fit
#include <stdio.h>
#include<stdlib.h>
int disk[20]:
struct blocks{
int bid;
int size;
int index;
int status;
}block;
struct processs
int pid;
int size;
int flag;
struct blocks b;
int fragment;
}process;
int main0{
int nb, np, i ,j;
int disk_index=0;
printf(" Total disk size is 50 \n");
printf(" enter numebr of blocks: "):
scanf("%d", &nb):
struct blocks bls[nb], temp;
for(i=0;i<nb;i++){
bls[i].bid=i;
printf("enter the size of block %d", i);
scanf("%d", &bls[il.size);
bls[i].index=disk_index;
disk_index=disk_index+bls[i].size;
bls[i].status = -1;
for(i=0;i<np;i++){
for(j=0:j<nb;j++)
if(bls[j].size > ps[i].size && bls[j].status ==-1)
ps[i].b=bls[jl:
bls[i].status = 1;
break;
}}}
printf(" \n now process block allocation list is \n");
for(i=0;i<np;i++){
printf(" process id: %d process size %d block id %d free space %dn", ps{i].pid,
psli].size, psli].b.bid, ps[i].b.size-ps[i].size);:
return 0;
}
Process ID Process_size
Process 0 3
Process 1
Process 2
Output:
now process block allocation list is
process id: 0 process size 4 block id 0 free space 1
process id: 1 process size 2 block id 1 free space 2
process id: 2 process size 3 block id 2 free space 5
EXPERIMENT -6
Objective- Calculation of Internal and External fragmentation
i. Free space list of blocks from system
ii. List process file from the system
Theory -
1. Fres space list of blocks from system
External Fragmentation:
External fragmentation happens when there's asufficient quantity of area within the memory to satisfy
the memory request of a method. However, the process's memory request cannot be fulfilled because
the memory offered is during a non-contiguous manner. Either you apply first-fit or best-fit memory
allocation strategy it'll cause external fragmentation.
Process 07
needs 50KB
40 KB memory space
Fragment
Assigned
Space
Fragment |10 KB
Assigned
Space
Fragment 5 KB
Input: Program 6:
Disk size = 20
Block ID Blocksize
Block 0
Block 1 4
Block 2 8
Block 3 3
Output:
now Free space list of blocks is
Block id: 2 Block size 3 block index 9
Total external free space is: 3
2. List process file from the system
Internal Fragmentation:
Internal fragmentation happens when the memory is split into mounted sized blocks. Whenever, a
method request for the memory, the mounted sized block is allotted to the method. Just in case, the
memory allotted to the method is somewhat larger than the memory requested, then the distinction
between allotted and requested memory is that the internal fragmentation.
Assigned
Fragment
Space
Used
< Space
Fragment
Assigned Used
Space
Space
Internal Fragmentation
Figure. Internal Fragmentation
Example program for List process file from the system
#include <stdio.h>
#include<stdlib.h>
int disk[201:
struct blocks{
int bid;
int size;
int index;
int status;
}block;
struct processs
int pid;
int size;
int flag:
struct blocks b;
int fragment;
}process;
int main(){
int nb, np, i,j:
int disk_index=0;
printf(" Total disk size is 50 \n");
printf(" enter numebr of blocks: "):
scanf("%d", &nb);
struct blocks bls[nb], temp;
for(i=0;i<nb;i++){
bls[i].bid=i;
printf("enter the size of block %d", i);
scanf("%d", &bls[i].size);
bls[i].index=disk_index;
disk_index=disk_index+bls[i].size;
bls[i].status = -1;
printf(" enter numebr of process: "):
scanf("%d",&np):
struct processs ps[np];
for(i=0;i<np;i++){
psli].pid=i;
printf("enter the size of process %d ", );
scanf("%d", &ps[i].size):
ps[i].flag=-1;
for(i=0;i<np;i++){
for(j=0:j<nb;j++){
if(bls[j].size > ps[i].size && bls[j].status ==-1){
psli].b=bls[jl:
bls[j].status = 1;
break;
Block ID Block
_size
Block 0 5
Block 1 1
Block 2 8
Block 3 3
Process ID Processsize
Process 0
Process 1 2
Process 2 4
Output:
now process block allocation list is
process id: 0 process size 4 block id 0 free space 1
process id: 1process size 2 block id 1 free space 2
process id: 2 process size 3 block id 2 free space 5
Theory -
Memory compaction
The longstanding memory fragmentation problem has been covered many times in these pages. In
short: as the system runs, pages tend to be scattered between users, making it hard to find groups of
physically-contiguous pages when they are needed. Much work has gone into avoiding the need for
higher-order (multi-page) memory allocations whenever possible, with the result that most kernel
functionality is not hurt by page fragmentation. But there are still situations where higher-order
allocations are needed; code which needs such allocations can fail on a fragmented system.
Example:
Figure: Memory status (where red part are the occupied block and white cells free memory)
Movable
pages
Example program for Implementation of compaction for the continually changing memory
layout and caleulate total movement of data
#include<stdio.h>
#include<stdlib.h>
int disk[20];
struct blocks
int bid;
int size;
int index;
int status;
}block;
struct processs
int pid;
int size;
int flag;
struct blocks b:
int fragment;
}process;
int main(0{
int nb, np, i,j:
int disk index-0;
printf(" Total disk size is 50 \n");
printf(" enter numebr of blocks: ");
scanf("%d", &nb);
struct blocks bls[nb], temp;
for(i-0;i<nb;i++) {
bls[i].bid=i;
printf("enter the size of block 9%d ", i);
scanf("%d", &bls[i].size);
bls[i].index=disk_index;
disk index-disk index+bls[i].size;
bls[i].status =-1;
printf(" enter numebr of process: ");
scanf("%d",&np);
struct processs ps[np]:
for(i-0;i<np;it+){
ps[il.pid-i;
printf("enter the size of process %d ", i):
scanf("%d", &ps[i].size);
ps[i].flag=-1;
for(i-0;i<np;it+){
for(j-0j<nb;j++)
if(bls[j].size > ps[i].size && blsi].status --1){
ps[i].b-blsil:
bls[i].status = 1;
break;
else
count = count +1:
i-itcount;
i=i-count;
Input: Program 7:
Block ID Block size
Block 0 3
Block 1 8
Block 2 5
Block 3
Output:
now process block allocation list is
Theory -
Resource Allocation Graph (RAG)
As Banker's algorithm using some kind of table like allocation, request, available all that thing to
understand what is the state of the system. Similarly, if you want to understand the state of the
system instead of using those table, actually tables are very easy to represent and understand it, but
then stillyou could even represent the same information in the graph. That graph is called Resource
Allocation Graph (RAG).
So, resource allocation graph is explained to us what is the state of the system in terms of processes
and resources. Like how many resources are available, how many are allocated and what is the
request of each process. Everything can be represented in terms of the diagram. One of the
advantages of having a diagram is, sometimes it is possible to see a deadlock directly by using RAG,
but then you might not be able to know that by looking at the table. But the tables are better if the
system contains lots of process and resource and Graph is better if the system contains less number
of process and resource.
We know that any graph contains vertices and edges. So RAG also contains vertices and edges. In
RAG vertices are two type
1. Process vertex- Every process will be represented as a process vertex.Generally, the process will
be represented with a circle.
2. Resource vertex Every resource will be represented as a resource vertex.
R1
P1 P2
P2 is holding R2
P1is waiting for R2
R2
for(i-0;i<np;it+){
printf("enter the number of resources process %d, holding", i);
scanf("%od", &temp):
for(j-0; j<temp:j++){
printf("enter the ressorce number process %d holding: ",);
scanf("%d", &templ);
rag[np+temp1][i]=1;
for(i-0;i<np+nr;it+){
for(j-0; j<np+nrj++){
printf("%d ", rag[i][iD:
printf("n");
return 0;
Input: Program 8:
Output:
PO P P2 RO RI R2
PO 0 00001
P1000100
P20 0 0 0 10
RO 100000
RI01 0 000
R200 1 000
EXPERIMENT-9
Objective Implementation of Banker's Algorithm
Theory
Banker's Algorithm
The Banker's algorithm a resource allocation and deadlock avoidance algorithm that tests for safety by
simulating the allocation for predetermined maximum possible amounts of all resources, then makes an s
state" check to test for possible activities, before deciding whether allocation should be allowed to continue.
Following Data structures are used to implement the Bankers Algorithm:
Let 'n' be the number of processes in the system and 'm' be the number of resources types.
Available:
It is a 1-d array of size m' indicating the number of available resources of each type.
Availablelj] =kmeans there are k' instances of resource type Rj
Max:
It is a 2-d array of size 'n*m' that defines the maximum demand of each process in a system.
Max[ i,j]=kmeansprocess Pi may request at most k instances of resourcetype Rj.
Allocation:
It is a 2-d array of size n*m' that defines the number of resources of each type currently allocated to
each process.
Allocation[ i,j]=k means process Pi is currently allocated k' instances of resource type Rj
Need :
It is a 2-d array of size n*m' that indicates the remaining resource need of each process.
Need [i, j]=kmeans process Pi currently need 'k' instances of resource type Rj
for its execution.
Need [ i, j]= Max [i, j]-Allocation [ i, j]
Allocation; specifies the resources currently allocated to process P, and Need; specifies the additional resources
that process P, may still request to complete its task.
Banker's algorithm consists of Safety algorithm and Resource request algorithm.
Safety Algorithm
1) Let Work and Finish be vectors of length 'm' and 'n' respectively.
Initialize: Work = Available
Finish[i] = false; for i=l, 2, 3, 4..n
2) Find an isuch that both
a) Finish[i] = false
b) Need;<= Work
if no such iexists goto step (4)
3) Work = Work + Allocation[i]
Finish[i]=true
goto step (2)
4) if Finish [i] = true for alli
then the system is in a safe state
Resource-Request Algorithm
Let Request; be the request array for process P. Request; [i] =k means process P wants k instances of
resource type R,. When a request for resources is made by process Pi, the following actions are taken:
1)If Request;<= Need;
Goto step (2);otherwise, raise an error condition,since the process has exceeded its maximum claim.
2) If Request;<= Available
Goto step (3); otherwise, P; must wait, since the resources are not available.
3) Have the system pretend to have allocated the requested resources to process Pi by modifying the state as
follows:
Available = Available - Requesti
Allocation, = Allocation; + Request;
Need; = Need;- Requesti
Example program for Implementation of Banker"s algorithm
#include <stdio.h>
Int main){
intn, m, i, j, k;
n=5;
m=3;
intalloc[5][3] = {{0, 1, 0}. {2, 0, 0 ), {3, 0, 2 }, {2, 1, 1 }, {0, 0, 2 } }:
intmax[5][3]= {{7, 5, 3 }. { 3, 2, 2 }. { 9, 0, 2 }, { 2, 2, 2 }.{ 4, 3, 3 } }:
intavail[3]= {3, 3,2 );
intf[n], ans[n], ind = 0;
for(k = 0; k <n; k++)
f[k] = 0;
intneed[nl[m];
for(i =0;i<n; i++){
for(j = 0; j < m; j++)
need[i][j]= max{il[j] - alloc[i][jl;
inty = 0;
for(k = 0; k < 5; k++) {
for(i = 0; i<n; it+) {
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++)
availly] += alloc[illyl;
f[i] = 1;
Input: Program 9:
Process Allocation Max Available
AB C A BC ABC
Po 0 1 0 75 3 3 3 2
P1 2 0 0 3 2 2
P 3 0 2 902
P 2 1 1 2 2 2
P 00 2 4 3 3
Output:
Following is the SAFE Sequence
PI-> P3 -> P4 -> PO -> P2
EXPERIMENT - 10
Objective -Conversion of resource allocation graph (RAG) to wait for graph (WFG) for cach type of method
used for storing graph.
Theory -
Wait-for-Graph (WFG)
A Wait-For Graph (WFG) is the same as the SRAG with the resource elements stripped out.
Example:
P2
2heleng2
PEHingtr
}
for(i-=0;i<np;i++){
printf("enter the number of resources process %d, holding", i);
scanf("%d", &temp):
forj=0; j<temp:j++){
printf("enter the ressorce number process %d holding: ", );
scanf("%d", &templ);
rag[np+temp1][i]=1;
printf("\n ");
int wfg[npllnp};
for(i=0;i<np;i++){
for(j=0; j<npj++){
wfglil[j]=0;
int k;
for(i=0;i<np;i++){
for(j=np:j<np + nr; j++){
if(rag[il[jl == 1){
for(k=0;k<np:k++){
if(raglil[k] == 1)
wfgli][k] = 1;
}
fori=0;i<np;i++){
for(j=0; j<npj++){
printf("%d ", wfglil[jl:
printf("n ");
return 0: