Os Lab
Os Lab
PAGE
EXP NO EXPERIMENT NAME MARKS SIGN
NO
TOTAL MARKS:
AIM:
To familiarize with Linux basic commands, directory structure, file and directory operations.
DESCRIPTION
(m) man: -It is used to get the manual of each of the commands.
Directory structure:
The Unix operating system consists of a single file system. All the controlling directories is present in the
main file system termed as the root directory of the operating system. The different directories in the root
are as follows:
-The initial program to be loaded on to the ram and the kernel is situated in this
directory.
-All the known devices will have a description and the newly installed
devices will have an entry in this directory.
(4) etc: -This is used to store the configuration files of the system.
-User login is directed to this and all home directory files are here.
(8) mnt: -All the mounted drives details will be stored here.
-All the processes are here and process ids are displayed as sub-
directories which contains its resources.
(11) lost+found: -This is an administrative level directory that contains recovery bits for
the deleted files or applications.
(13) sbin: -This also contains system administrative files but can be
accessed by all users.
(15) sys: -This contains system related files like power related files.
(18) var: -This is used to store variable files like system logs.
SEMAPHORES IMPLEMENTATION
AIM:
Write a C program to implement the Producer consumer problem using semaphores
Semaphore is a simply a variable. This variable is used to solve critical section problem and to achieve
process synchronization in the multi-processing environment.
The two most common kinds of semaphores are counting semaphores and binary semaphores.
Semaphores are of two types:
1. Binary Semaphore – This is also known as mutex lock. It can have only two values – 0 and
1. Its value is initialized to 1. It is used to implement solution of critical section problem 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.
P and V are the two operations which can be used to access and change the value of semaphore variable
1. P operation is also called wait, sleep or down operation and V operation is also called
signal, wake-up or up operation.
2. Both operations are atomic and semaphore(s) is always initialized to one.
3. The wait() operation reduces the value of semaphore by 1 and the signal() operation
increases its value by 1.
4. A critical section is surrounded by both operations to implement process synchronization. See
below image. Critical section of Process P is in between P and V operation
do{
e); switch(choice){
}while(choice!=3);
}
a) Round Robin
b) SJF
c) FCFS
d)Priority
FCFS: First Come First Serve Scheduling
The process with the minimal arrival time will get the CPU first.
The lesser the arrival time, the sooner will the process gets the CPU.
The Turnaround time and the waiting time are calculated by using the following formula.
0 0 2 2 2 0
1 1 6 8 7 1
2 2 4 12 8 4
3 3 9 21 18 9
4 4 12 33 29 17
The waiting time is 3 milliseconds for process P1, 16 milliseconds for process P2, 9 milliseconds for
process P3, and 0 milliseconds for process P4. Thus, the average waiting time is (3 + 16 + 9 + 0)/4 = 7
milliseconds. By comparison, if we were using the FCFS scheduling scheme, the average waiting time
would be 10.25 milliseconds.
Priority Scheduling
The SJF algorithm is a special case of the general priority-scheduling algorithm. Apriority is associated
with each process, and the CPUis allocated to the process with the highest priority. Equal- priority processes
are scheduled in FCFS order. An SJF algorithm is simply a priority algorithm where thepriority (p) is the
inverse of the (predicted) next CPU burst. The larger the CPU burst, the lower the priority, and vice versa.
Note that we discuss scheduling in terms of high priority and low priority.
Round-Robin Scheduling
The round-robin (RR) scheduling algorithm is designed especially for timesharing systems. It is similar to
FCFS scheduling, but preemption is added to enable the system to switch between processes. A small unit
of time, called a time quantum or time slice, is defined. A time quantum is generally from 10 to 100
milliseconds in length. The ready queue is treated as a circular queue. The CPU scheduler goes around the
ready queue, allocating the CPU to each process for a time interval of up to 1 time quantum.
To implement RR scheduling, we again treat the ready queue as a FIFO queue of processes. New processes
are added to the tail of the ready queue. The CPU scheduler picks the first process from the ready queue,
sets a timer to interrupt after 1 time quantum, and dispatches the process. One of two things will then
happen. The process may have a CPU burst of less than 1 time quantum. In this case, the process itself will
release the CPU voluntarily. The scheduler will then proceed to the next process in the ready queue. If the
CPU burst of the currently running process is longer than 1 time quantum, the timer will go off and will
cause an interrupt to the operating system. A context switch will be executed, and the process will be put at
the tail of the ready queue. The CPU scheduler will then select the next process in the ready queue.
Let’s calculate the average waiting time for this schedule. P1 waits for 6 milliseconds (10 - 4), P2 waits for
4 milliseconds, and P3 waits for 7 milliseconds. Thus, the average waiting time is 17/3 = 5.66
#include<stdio.h>
void main()
{
int i=0,j=0,b[i],g[20],p[20],w[20],t[20],a[20],n=0,m;
float avgw=0,avgt=0;
printf("Process ID : ");
scanf("%d",&p[i]);
printf("Burst Time : ");
scanf("%d",&b[i]);
printf("Arrival Time: ");
scanf("%d",&a[i]);
}
int temp=0;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1;j++)
if(a[j]>a[j+1])
temp=a[j];
}
g[0]=0;
for(i=0;i<=n;i++)
g[i+1]=g[i]+b[i];
for(i=0;i<n;i++)
{
t[i]=g[i+1]-a[i];
w[i]=t[i]-b[i];
avgw+=w[i];
avgt+=t[i];
}
avgw=avgw/n;
avgt=avgt/n;
printf("pid\tarrivalT\tBrustT\tCompletionT\tWaitingtime\tTurnaroundTi\n");
for(i=0;i<n;i++)
{
Output
1 0 4 4 0 4
2 1 3 7 3 6
3 2 1 8 5 6
4 3 2 10 5 7
5 4 5 15 6 11
#include<stdio.h>
void main()
{
int i=0,j=0,p[i],b[i],g[20],w[20],t[20],a[20],n=0,m;
int k=1,min=0,btime=0;
float avgw=0,avgt=0;
printf("Enter the number of process : ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nProcess id : ");
scanf("%d",&p[i]);
temp=b[j];
b[j]=b[j+1];
b[j+1]=temp;
temp=p[j];
p[j]=p[j+1];
p[j+1]=temp;
}
}
}
for(i=0;i<n;i++)
{
btime=btime+b[i];
min=b[k];
for(j=k;j<n;j++)
{
if(btime >= a[j] && b[j]<min)
{
temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
temp=b[j];
b[j]=b[j-1];
b[j-1]=temp;
temp=p[j]
}
} k++;
g[0]=a[0];
for(i=0;i<n;i++)
{
g[i+1]=g[i]+b[i];
if(g[i]<a[i])
g[i]=a[i];
}
for(i=0;i<n;i++)
{
t[i]=g[i+1]-a[i];
w[i]=t[i]-b[i];
avgw+=w[i];
avgt+=t[i];
}
avgw=avgw/n;
avgt=avgt/n;
printf("pid\tBrustTime\tGantChart\tWaiting time\t\tTurnarround Time\n"); for(i=0;i<n;i+
+)
{
printf(" %d\t %d\t\t%d-%d\t\t%d\t\t\t%d\n",p[i],b[i],g[i],g[i+1],w[i],t[i]);
}
printf("\nAverage waiting time %f",avgw);
printf("\nAverage turnarround time %f\n",avgt);
Process id : 1 Burst
Time : 7 Arrival
Time: 0
Process id : 2 Burst
Time : 5
Arrival Time: 1
Process id : 3 Burst
Time : 1 Arrival Time:
2
Process id : 4 Burst
Time : 2 Arrival Time:
3
Process id : 5 Burst
Time : 8 Arrival Time:
#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];
Process id : 1
Burst Time : 15
Priority: 3
Process id : 2
Burst Time : 10
Priority: 2
Process id : 3 Burst
Time : 90
Priority: 1
#include<stdio.h>
int main()
{
int i, limit, total = 0, x, counter = 0, time_quantum;
int wait_time = 0, turnaround_time = 0, arrival_time[10], burst_time[10], temp[10]; float
average_wait_time, average_turnaround_time;
printf("\nEnter Total Number of Processes:\t");
scanf("%d", &limit);
x = limit;
for(i = 0; i < limit; i++)
{
total = total + temp[i];
temp[i] = 0;
counter = 1;
}
else if(temp[i] > 0)
{
temp[i] = temp[i] - time_quantum; total
= total + time_quantum;
}
if(temp[i] == 0 && counter == 1)
{
x--;
printf("\nProcess[%d]\t\t%d\t\t %d\t\t\t %d", i + 1, burst_time[i], total - arrival_time[i], total -
arrival_time[i] - burst_time[i]);
wait_time = wait_time + total - arrival_time[i] - burst_time[i];
turnaround_time = turnaround_time + total - arrival_time[i];
counter = 0;
Process id : 2 Burst
Time : 3 Arrival
Time:2
Process id : 3 Burst
Time : 2 Arrival
Time:3
AIM:
a) First Fit
b) Worst Fit
c) Best Fit
First Fit
In the first fit approach is to allocate the first free partition or hole large enough which can accommodate the
process. It finishes after finding the first suitable free partition.
Best Fit
The best fit deals with allocating the smallest free partition which meets the requirement of the requesting process.
This algorithm first searches the entire list of free partitions and considers the smallest hole that is adequate. It then
tries to find a hole which is close to actual process size needed.
Worst fit
In worst fit approach is to locate largest available free portion so that the portion left will be big enough to be
useful. It is the reverse of best fit.
PROGRAM
1. FIRST FIT
#include<stdio.h>
struct process
{
int ps;
int flag;
} p[50];
struct sizes
{
OUTPUT
First fit
1 40 100
2 200 250
3 300 300
2. WORST FIT
#include<stdio.h>
int main()
{
scanf("%d", &blocks[m]);
scanf("%d", &files[m]);
if(block_arr[n] != 1)
file_arr[m] = n;
top = temp;
}
fragments[m] = top;
block_arr[file_arr[m]] = 1;
top = 0;
printf("\n");
return 0;
}
OUTPUT
Block No.[1] : 50
Block No.[2] : 75
File No.[1] : 20
File No.[3] : 40
0 20 3 300 280
1 100 0 50 0
2 40 0 50 10
#include<stdio.h>
#define MAX 20
int main()
{
int bsize[MAX],fsize[MAX],nb,nf;
int temp,low=10000;
static int bflag[MAX],fflag[MAX]; int
i,j;
printf("\n enter the number of blocks");
scanf("%d",&nb);
for(i=1;i<=nb;i++)
{
printf("Enter the size of memory block % d",i);
scanf("%d", &bsize[i]);
}
printf("\n enter the number of files");
scanf("%d",&nf);
for(i=1;i<=nf;i++)
{
printf("\n enetr the size of file %d",i);
scanf("%d",&fsize[i]);
}
for(i=1;i<=nf;i++)
{
for(j=1;j<=nb;j++)
{
if(bflag[j]!=1)
{
temp=bsize[j]-fsize[i];
if(temp>=0)
{
if(low>temp)
{
OUTPUT
1 50 4 50
2 20 1 40
23 225 3 250
AIM:
Initially all slots are empty, so when 1, 3, 0 came they are allocated to the empty slots —> 3 Page Faults.
when 3 comes, it is already in memory so —> 0 Page Faults.
Then 5 comes, it is not available in memory so it replaces the oldest page slot i.e 1. —>1 Page Fault.
6 comes, it is also not available in memory so it replaces the oldest page slot i.e 3 —>1 Page Fault.
Finally when 3 come it is not available so it replaces 0 1 page fault
#include<stdio.h> int
main()
{
printf("%d\t\t",a[i]); avail=0;
for(k=0;k<no;k++)
if(frame[k]==a[i]) avail=1;
if(avail==0)
{
frame[j]=a[i];
j=(j+1)%no; count++;
for(k=0;k<no;k++)
printf("\n");
OUTPUT
0 1 7 0 1
7 -1 -1
7 0 -1
7 0 1
2 0 1
2 3 1
2 3 0
2 0 3
4 3 0
4 2 0
4 2 3
0 2 3
0 1 3
0 1 2
7 1 2
7 0 2
7 0 1
#include<stdio.h>
int findLRU(int time[], int n){
int i, minimum = time[0], pos = 0;
int main()
{
int no_of_frames, no_of_pages, frames[10], pages[30], counter = 0, time[10], flag1, flag2, i, j, pos, faults =
0;
printf("Enter number of frames: ");
scanf("%d", &no_of_frames);
printf("Enter number of pages: ");
scanf("%d", &no_of_pages);
printf("Enter reference string: ");
for(i = 0; i < no_of_pages; ++i){
scanf("%d", &pages[i]);
}
if(flag1 == 0){
for(j = 0; j < no_of_frames; ++j){
if(frames[j] == -1){ counter++;
faults++;
frames[j] = pages[i];
time[j] = counter;
flag2 = 1;
break;
}
}
}
if(flag2 == 0){
pos = findLRU(time, no_of_frames);
counter++;
faults++;
frames[pos] = pages[i];
time[pos] = counter;
}
printf("\n");
return 0;
}
OUTPUT
0 1 7 0 1
7 -1 -1
7 0 -1
7 0 1
2 0 1
2 0 1
2 0 3
2 0 3
4 0 3
4 0 2
4 3 3
0 3 2
0 3 2
0 3 2
1 3 2
1 3 2
1 0 2
1 0 2
1 0 7
1 0 7
1 0 7
#include<stdio.h>
int main()
{
int no_of_frames, no_of_pages, frames[10], pages[30], temp[10], flag1, flag2, flag3, i, j, k, pos, max,
faults = 0;
printf("Enter number of frames: ");
scanf("%d", &no_of_frames);
if(flag1 == 0){
for(j = 0; j < no_of_frames; ++j){
if(frames[j] == -1){
if(flag2 == 0){
flag3 =0;
if(flag3 ==0){
max = temp[0];
pos = 0;
printf("\n");
return 0;
OUTPUT
0 1 7 0 1
7 -1 -1
7 0 -1
7 0 1
2 0 1
2 0 1
2 0 3
2 4 3
2 4 3