OS Manual AI & ML-1
OS Manual AI & ML-1
Sl.NO Experiments
1 Develop a c program to implement the Process system calls (fork (), exec(), wait(), create process,
terminate process)
2 Simulate the following CPU scheduling algorithms to find turnaround time and waiting time a)
FCFS
b) SJF c) Round Robin d) Priority.
3
Develop a C program to simulate producer-consumer problem using semaphores.
4 Develop a C program which demonstrates interprocess communication between a reader
process and a writer process. Use mkfifo, open, read, write and close APIs in your program.
5
Develop a C program to simulate Bankers Algorithm for DeadLock Avoidance.
6 Develop a C program to simulate the following contiguous memory allocation Techniques:
a) Worst fit b) Best fit c) First fit.
7 Develop a C program to simulate page replacement algorithms:
a) FIFO b) LRU
8 Simulate following File Organization Techniques
a) Single level directory b) Two level directory
9 Develop a C program to simulate the Linked file allocation strategies.
10
Develop a C program to simulate SCAN disk scheduling algorithm.
Course outcomes (Course Skill Set):
At the end of the course, the student will be able to:
CO 1. Explain the structure and functionality of operating system
CO 2. Apply appropriate CPU scheduling algorithms for the given problem.
CO 3. Analyse the various techniques for process synchronization and deadlock handling.
CO 4. Apply the various techniques for memory management
CO 5. Explain file and secondary storage management strategies.
CO 6. Describe the need for information protection mechanisms
Assessment Details (both CIE and SEE)
The weightage of Continuous Internal Evaluation (CIE) is 50% and for Semester End Exam (SEE) is
50%. The minimum passing mark for the CIE is 40% of the maximum marks (20 marks out of 50) and
for the SEE minimum passing mark is 35% of the maximum marks (18 out of 50 marks). A student
shall be deemed to have satisfied the academic requirements and earned the credits allotted to each
subject/ course if the student secures a minimum of 40% (40 marks out of 100) in the sum total of the
CIE (Continuous Internal Evaluation) and SEE (Semester End Examination) taken together.
CIE for the theory component of the IPCC (maximum marks 50)
● IPCC means practical portion integrated with the theory of the course.
● CIE marks for the theory component are 25 marks and that for the practical component is 25 marks.
● 25 marks for the theory component are split into 15 marks for two Internal Assessment Tests
(Two Tests, each of 15 Marks with 01-hour duration, are to be conducted) and 10 marks for
other assessment methods
mentioned in 22OB4.2. The first test at the end of 40-50% coverage of the syllabus and the second test
after covering 85-90% of the syllabus.
● Scaled-down marks of the sum of two tests and other assessment methods will be CIE marks for
the theory component of IPCC (that is for 25 marks).
● The student has to secure 40% of 25 marks to qualify in the CIE of the theory component of IPCC.
CIE for the practical component of the IPCC
● 15 marks for the conduction of the experiment and preparation of laboratory record, and 10 marks
for the test to be conducted after the completion of all the laboratory sessions.
● On completion of every experiment/program in the laboratory, the students shall be evaluated
including viva- voce and marks shall be awarded on the same day.
● The CIE marks awarded in the case of the Practical component shall be based on the continuous
evaluation of the laboratory report. Each experiment report can be evaluated for 10 marks. Marks of
all experiments’ write- ups are added and scaled down to 15 marks.
● The laboratory test (duration 02/03 hours) after completion of all the experiments shall be
conducted for 50 marks and scaled down to 10 marks.
● Scaled-down marks of write-up evaluations and tests added will be CIE marks for the laboratory
component of IPCC for 25 marks.
● The student has to secure 40% of 25 marks to qualify in the CIE of the practical component of the IPCC.
SEE for IPCC
Theory SEE will be conducted by University as per the scheduled timetable, with common question
papers for the course (duration 03 hours)
1. The question paper will have ten questions. Each question is set for 20 marks.
2. There will be 2 questions from each module. Each of the two questions under a module (with a
maximum of 3 sub-questions), should have a mix of topics under that module.
3. The students have to answer 5 full questions, selecting one full question from each module.
4. Marks scored by the student shall be proportionally scaled down to 50 Marks
The theory portion of the IPCC shall be for both CIE and SEE, whereas the practical portion
will have a CIE component only. Questions mentioned in the SEE paper may include questions
from the practical component.
CONTENTS
1. Introduction 6
Perform a case study by installing and exploring various types of operating systems on a physical
or logical (virtual) machine. (Linux Installation). Instructions to Install Ubuntu Linux 18.04
(LTS) along with Windows Back Up Your Existing Data!
This is highly recommended that you should take backup of your entire data before start with the
installation process.
Before booting the installation system, one need to change the boot order and set CD-ROM as first
boot device.
Changing the Boot Order of a Computers
As your computer starts, press the DEL-F10, HP-F9 during the initial startup screen. Depending on
the BIOS manufacturer, a menu may appear. However, consult the hardware documentation for the
exact key strokes.
Beneath the installation-type question are two checkboxes; one to enable updates while installing and
another to enable third-party software.
We advise enabling both Download updates and Install third-party software.
Stay connected to the internet so you can get the latest updates while you install Ubuntu.
If you are not connected to the internet, you will be asked to select a wireless network, if
available. We advise you to connect during the installation so we can ensure your machine
is up to date.
Use the checkboxes to choose whether you’d like to install Ubuntu alongside another operating
system, delete your existing operating system and replace it with Ubuntu, or — if you’re an advanced
user — choose the ’Something else’ option.
Begin installation
After configuring storage, click on the ‘Install Now’ button. A small pane will appear with an
overview of the storage options you’ve chosen, with the chance to go back if the details are incorrect.
Click Continue to fix those changes in place and start the installation process.
If you are connected to the internet, your location will be detected automatically. Check your
location is correct and click ’Forward’ to proceed.
If you’re unsure of your time zone, type the name of a local town or city or use the map to select
your location.
Positive: If you’re having problems connecting to the Internet, use the menu in the top-right-hand
corner to select a network.
Login details
Enter your name and the installer will automatically suggest a computer name and username. These
can easily be changed if you prefer. The computer name is how your computer will appear on the
network, while your username will be your login and account name.
Next, enter a strong password. The installer will let you know if it’s too weak.
You can also choose to enable automatic login and home folder encryption. If your machine is
portable, we recommend keeping automatic login disabled and enabling encryption. This should stop
people accessing your personal files if the machine is lost or stolen.
If you enable home folder encryption and you forget your password, you won’t be able to retrieve
any personal data stored in your home folder.
Background installation
The installer will now complete in the background while the installation window teaches you a little
about how awesome Ubuntu is. Depending on the speed of your machine and network connection,
installation should only take a few minutes.
Installation complete
After everything has been installed and configured, a small window will appear asking you to restart
your machine. Click on Restart Now and remove either the DVD or USB flash drive when prompted.
If you initiated the installation while testing the desktop, you also get the option to continue testing.
Congratulations! You have successfully installed the world’s most popular Linux operating system!
It’s now time to start enjoying Ubuntu!
PROGRAM 1:
Develop a c program to implement the Process system calls (fork (), exec(), wait(), create
process, terminate process)
System Calls:
The interface between a process and an operating system is provided by system calls. In general,
system calls are available as assembly language instructions. They are also included in the manuals
used by the assembly level programmers. System calls are usually made when a process in user mode
requires access to a resource. Then it requests the kernel to provide the resource via a system call.
If a file system requires the creation or deletion of files. Reading and writing from files also require
a system call.
Creation and management of new processes.
Network connections also require system calls. This includes sending and receiving packets.
Access to a hardware devices such as a printer, scanner etc. requires a system call
There are mainly five types of system calls. These are explained in detail as follows −
Process Control
These system calls deal with processes such as process creation, process termination etc.
File Management
These system calls are responsible for file manipulation such as creating a file, reading a file, writing
into a file etc.
Device Management
These system calls are responsible for device manipulation such as reading from device buffers,
writing into device buffers etc.
Information Maintenance
These system calls handle information and its transfer between the operating system and the user
program.
Communication
These system calls are useful for inter process communication. They also deal with creating and
deleting a communication connection.
fork ( )
Used to create new process. The new process consists of a copy of the address space of the
original process. The value of process id for the child process is zero, whereas the value of process id
for the parent is an integer value greater than zero.
Syntax: fork ( );
wait ( )
The parent waits for the child process to complete using the wait system call. The wait system call
returns the process identifier of a terminated child, so that the parent can tell which of its possibly
many children has terminated.
Syntax: wait (NULL);
exit ( )
A process terminates when it finishes executing its final statement and asks the operating
system to delete it by using the exit system call. At that point, the process may return data (output) to
its parent process (via the wait system call).
Syntax: exit (0)
DESCRIPTION:
Used to create new processes. The new process consists of a copy of the address space of the original
Process. The value of process id for the child process is zero, whereas the value of process id for the
parent is an integer value greater than zero.
Syntax: Fork ( );
ALGORITHM:
Step 1: Start the program.
Step 4: If child id value is greater than zero then print as “i am in the parent process”.
Step 5: If child id! = 0 then using getpid() system call get the process id.
Step 6: Print “i am in the parent process” and print the process id.
Step 7: If child id! = 0 then using getppid() system call get the parent process id.
Step 8: Print “i am in the parent process” and print the parent process id.
Step 9: Else If child id value is less than zero then print as “i am in the child process”.
Step 10: If child id! = 0 then using getpid() system call get the process id.
Step 11: Print “i am in the child process” and print the process id.
Step 12: If child id! = 0 then using getppid() system call get the parent process id.
Step 13: Print “i am in the child process” and print the parent process id.
PROGRAM :
SOURCE CODE:
#include<stdio.h>
#include <unistd.h>
#include<sys/types.h> int
main()
if((childid=fork())>0)
}
else
OUTPUT:
$ gedit fork.c
$ cc fork.c
$ ./a.out
RESULT:
ALGORITHM:
Step 3: Get the child id value using the system call fork ().
Step 4: If child id value is less than zero then print “fork failed”.
Step 5: Else if child id value is equal to zero, it is the id value of the child and then start the child
process to execute and perform Steps 7 & 8.
Step 7: Use a for loop for almost five child processes to be called.
Step 8: After execution of the for loop then print “child process
ends”.
Step 9: Execute the system call wait ( ) to make the parent to wait for the child process to get over.
Step 10: Once the child processes are terminated, the parent terminates and hence prints “Parent
process ends”.
Step 11: After both the parent and the child processes get terminated it execute the wait ( ) system
call to permanently get deleted from the OS.
SOURCE CODE:
/* wait system call */
#include <stdlib.h>
#include <errno.h>
#include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
main()
{
pid_t pid;
int rv;
switch(pid=fork())
case -1:
perror("fork");
exit(1);
case 0:
exit(rv);
default:
printf("\nPARENT: This is the parent process!\n"); printf("\
wait(&rv);
fflush(stdout);
%d\n",WEXITSTATUS(rv));
OUTPUT:
$ gedit wait.c
$ cc wait.c
$ ./a.out
10
Exec()
In execl() function, the parameters of the executable file is passed to the function as different arguments.
With execv(), you can pass all the parameters in a NULL terminated array argv. The first element of the
array should be the path of the executable file. Otherwise, execv() function works just as execl() function.
ALGORITHM:
Step 3: Print execution of exec system call for the ls Unix command.
Step 4: Execute the execv function using the appropriate syntax for the Unix command ls.
Step 5: The list of all files and directories of the system is displayed.
PROGRAM :
SOURCE CODE:
#include<stdio.h>
#include<sys/types.h> main(int
argc,char *argv[])
printf("before execv\n");
execv("/bin/ls",argv);
printf("after execv\n");
OUTPUT:
$ gedit execv.c
$ cc execv.c
$ ./a.out
before execv
a1 aaa aaa.txt abc a.out b1 b2 comm.c db db1 demo2 dir1 direc.c execl.c execv.c f1.txt fflag.c file1 file2
RESULT:
PROGRAM 2:
Simulate the following CPU scheduling algorithms to find turnaround time and waiting time a)
FCFS b) SJF c) Round Robin d) Priority.
CPU Scheduling Algorithms:
Scheduling of processes/work is done to finish the work on time.
Below are different times with respect to a process.
Arrival Time : Time at which the process arrives in the ready queue.
Completion Time : Time at which process completes its execution.
Burst Time : Time required by a process for CPU execution.
Turn Around Time : Time Difference between completion time and arrival time.
Turn Around Time = Completion Time - Arrival Time
Waiting Time(W.T) : Time Difference between turn around time and burst time.
Waiting Time = Turn Around Time - Burst Time
Why do we need scheduling?
A typical process involves both I/O time and CPU time. In a uniprogramming system like MS DOS,
time spent waiting for I/O is wasted and CPU is free during this time. In multiprogramming systems,
one process can use CPU while another is waiting for I/O. This is possible only with process
scheduling.
First Come First Serve (FCFS): Simplest scheduling algorithm that schedules according to arrival
times of processes. First come first serve scheduling algorithm process that requests the CPU first is
allocated the CPU first. It is implemented by using the FIFO queue. When a process enters the ready
Shortest Job First (SJF): Process which has the shortest burst time is scheduled first. If two
processes have the same bust time, then FCFS is used to break the tie. It is a non-preemptive
scheduling algorithm
DESCRIPTION:
ALGORITHM:
Step 1: Start the program.
Step 2: Create the number of process.
Step 3: Get the ID and Service time for each process.
Step 4: Initially, Waiting time of first process is zero and Total time for the first process is
the starting time of that process.
Step 5: Calculate the Total time and Processing time for the remaining processes.
Step 6: Waiting time of one process is the Total time of the previous process.
Step 7: Total time of process is calculated by adding Waiting time and Service time.
Step 8: Total waiting time is calculated by adding the waiting time for lack process.
Step 9: Total turn around time is calculated by adding all total time of each process.
Step 10: Calculate Average waiting time by dividing the total waiting time by total number of process.
Step 11: Calculate Average turn around time by dividing the total time by the number of process.
Step 12: Display the result.
Step 13: Stop the program.
PROGRAM:
SOURCE CODE:
/* A program to simulate the FCFS CPU scheduling algorithm */
#include<stdio.h>
int main()
{
char pn[10][10];
int arr[10],bur[10],star[10],finish[10],tat[10],wt[10],i,n; int
totwt=0,tottat=0;
printf("Enter the number of processes:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter the Process Name, Arrival Time & Burst Time:");
scanf("%s%d%d",&pn[i],&arr[i],&bur[i]);
}
for(i=0;i<n;i++)
{
if(i==0)
{
star[i]=arr[i]; wt[i]=star[i]-
arr[i]; finish[i]=star[i]
+bur[i]; tat[i]=finish[i]-
arr[i];
}
else
{
star[i]=finish[i-1];
wt[i]=star[i]-arr[i];
finish[i]=star[i]+bur[i];
tat[i]=finish[i]-arr[i];
OUTPUT:
$ cc fcfs.c
$ ./a.out
1 2 3 2 3 5
2 5 6 5 6 11
3 6 7 11 12 18
DESCRIPTION:
P0 0-0=0
P1 5-1=4
P2 14 - 2 = 12
P3 8-3=5
ALGORITHM:
Step 1: Start the program.
Step 2: Get the number of process.
Step 3: Get the id and service time for each process.
Step 4: Initially the waiting time of first short process as 0 and total time of first short is process the
service time of that process.
Step 5: Calculate the total time and waiting time of remaining process.
Step 6: Waiting time of one process is the total time of the previous process.
Step 7: Total time of process is calculated by adding the waiting time and service time of each process.
Step 8: Total waiting time calculated by adding the waiting time of each process.
Step 9: Total turn around time calculated by adding all total time of each process.
Step 10: Calculate average waiting time by dividing the total waiting time by total number of process.
Step 11: Calculate average turn around time by dividing the total waiting time by total number
of process.
Step 12: Display the result. Step 13: Stop the program.
PROGRAM:
SOURCE CODE:
/* A program to simulate the SJF CPU scheduling algorithm */
#include<stdio.h>
#include<string.h>
Void main()
{
int i=0,pno[10],bt[10],n,wt[10],temp=0,j,tt[10];
float sum,at;
printf("\n Enter the no of process ");
scanf("\n %d",&n);
printf("\n Enter the burst time of each process");
for(i=0;i<n;i++)
{
printf("\n p%d",i);
scanf("%d",&bt[i]);
}
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(bt[i]>bt[j])
{
temp=bt[i];
bt[i]=bt[j];
bt[j]=temp;
temp=pno[i];
pno[i]=pno[j];
pno[j]=temp;
}
}}
wt[0]=0;
for(i=1;i<n;i++)
{
wt[i]=bt[i-1]+wt[i-1];
sum=sum+wt[i];
}
printf("\n process no \t burst time\t waiting time \t turn around time\n");
for(i=0;i<n;i++)
{
tt[i]=bt[i]+wt[i];
at+=tt[i];
printf("\n p%d\t\t%d\t\t%d\t\t%d",i,bt[i],wt[i],tt[i]);
}
printf("\n\n\t Average waiting time%f\n\t Average turn around time%f", sum, at);
}
OUTPUT:
$ cc sjf.c
$ ./a.out
p0 1
p1 5
p2 2
p3 3
p4 4
p0 1 0 1
p1 2 1 3
p2 3 3 6
p3 4 6 10
p4 5 10 15
DESCRIPTION
ALGORITHM:
i. The waiting time for first instance of a process is calculated as: a[i].waittime=count + a[i].arrivt.
ii. The waiting time for the rest of the instances of the process is calculated as:
a) If the time quantum is greater than the remaining burst time then waiting time is calculated
as: a[i].waittime=count + tq.
b) Else if the time quantum is greater than the remaining burst time then waiting time is
calculated as: a[i].waittime=count - remaining burst time
Step 5: Calculate the average waiting time and average turnaround
time Step 6: Print the results of the step 4.
Step 7: Stop the program.
PROGRAM :
SOURCE CODE:
/* A program to simulate the Round Robin CPU scheduling algorithm */ #include<stdio.h>
struct process
{
int burst,wait,comp,f;
}
p[20]={0,0};
int main()
{
int n,i,j,totalwait=0,totalturn=0,quantum,flag=1,time=0;
while(flag==1)
{
flag=0; for(i=0;i<n;i++)
{
if(p[i].f==1)
{
flag=1;
j=quantum;
if((p[i].burst-p[i].comp)>quantum)
{
p[i].comp+=quantum;
}
else
{ p[i].wait=time-p[i].comp;
j=p[i].burst-p[i].comp;
p[i].comp=p[i].burst;
p[i].f=0;
}
printf("\nprocess #%-3d%-10d%-10d%-10d",i+1,time,time+j,p[i].burst- p[i].comp);
time+=j;
}
}
}
printf("\n\n ");
printf("\nProcess \t Waiting Time TurnAround Time ");
for(i=0;i<n;i++)
{
totalwait=totalwait+p[i].wait;
totalturn=totalturn+p[i].wait+p[i].burst;
}
printf("\n\nAverage\n--------------------------");
printf("\nWaiting Time: %fms",totalwait/(float)n);
return 0;
}
OUTPUT:
DEPT OF CSE-AI & ML, ATMECE, MYSURU
37
OPERATING SYSTEM LABORATORY BCS303
$ cc rr.c
$ ./a.out
process # 1 0 5 20
process # 2 5 10 25
process # 3 10 15 49
process # 1 15 20 15
process # 2 20 25 20
process # 3 25 30 44
process # 1 30 35 10
process # 2 35 40 15
process # 3 40 45 39
process # 1 45 50 5
process # 2 50 55 10
process # 3 55 60 34
process # 1 60 65 0
process # 2 65 70 5
process # 3 70 75 29
process # 2 75 80 0
process # 3 80 85 24
process # 3 85 90 19
process # 3 90 95 14
process # 3 95 100 9
Process # 2 50 80
Process # 3 55 109
Average ------------------ Waiting Time: 48.333333ms TurnAround
Time: 84.666667ms
PROGRAM :
Priority scheduling is a non-preemptive algorithm and one of the most common scheduling
algorithms in batch systems. Each process is assigned first arrival time (less arrival time process
first) if two processes have same arrival time, then compare to priorities (highest process first).
Also, if two processes have same priority then compare to process number (less process number
first). This process is repeated while all process get executed.
Implementation –
First input the processes with their arrival time, burst time and priority.
First process will schedule, which have the lowest arrival time, if two or more processes will
have lowest arrival time, then whoever has higher priority will schedule first.
Now further processes will be schedule according to the arrival time and priority of the
process. (Here we are assuming that lower the priority number having higher priority). If two
process priority are same then sort according to process number.
Note: In the question, They will clearly mention, which number will have higher priority
and which number will have lower priority.
Once all the processes have been arrived, we can schedule them based on their priority.
Consider the below table for processes with their respective CPU burst times and the priorities.
SOURCE CODE
#include<stdio.h>
scanf("%d",&n);
printf("\n Enter process : time priorities \n");
for(i=0;i<n;i++)
{
printf("\nProcess no %d : ",i+1);
scanf("%d %d",&pt[i],&pp[i]);
p[i]=i+1;
}
for(i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(pp[i]<pp[j])
{
x=pp[i];
pp[i]=pp[j];
pp[j]=x;
x=pt[i];
pt[i]=pt[j];
pt[j]=x;
x=p[i];
p[i]=p[j];
p[j]=x;
}
}
}
w[i]=t[i-1];
awt+=w[i];
t[i]=w[i]+pt[i];
atat+=t[i];
}
printf("\n\n Job \t Burst Time \t Wait Time \t Turn Around Time Priority \n");
for(i=0;i<n;i++)
printf("\n %d \t\t %d \t\t %d \t\t %d \t\t %d \n",p[i],pt[i],w[i],t[i],pp[i]);
awt/=n;
atat/=n;
printf("\n Average Wait Time : %d \n",awt);
OUTPUT:
Process no 2 : 4 2
Process no 3 : 5 3
Process no 4 : 6 4
4 6 0 6 4
3 5 6 11 3
2 4 11 15 2
1 3 15 18 1
PROGRAM 3:
PROGRAM
SOURCE CODE:
#include <stdio.h>
#include <stdlib.h>
int mutex = 1; // Initializing the mutex variable with the value 1.
int full = 0; // Initializing the full variable with the value 0.
Int empty = 10, data = 0; // empty variable will store the number of empty slots in the buffer
void producer()// A function that will resemble producers' production of data
{
--mutex; // decrementing the value of mutex
++full; // Increase the number of full slots
--empty; // decrementing the number of slots available
data++;// incrementing data which means that the data is produced
printf("\nProducer produces item number: %d\n", data);
++mutex; // incrementing the value of mutex
}
void consumer()// A function that will resemble the consumer's consumption of data
{
--mutex;
--full;
++empty;
printf("\nConsumer consumes item number: %d.\n", data); data--;
++mutex;
}
int main()
{
int n, i;
printf("\n1. Enter 1 for Producer" "\n2.
Enter 2 for Consumer" "\n3.
OUTPUT:
$ cc rr.c
$ ./a.out
1. Enter 1 for Producer
2. Enter 2 for Consumer
3. Enter 3 to Exit Enter
your choice: 1
Producer produces item number: 1
Enter your choice: 1
Producer produces item number: 2
Enter your choice: 1
Producer produces item number: 3
Enter your choice: 2
Consumer consumes item number: 3.
Enter your choice: 2
Consumer consumes item number: 2.
Enter your choice: 2
Consumer consumes item number: 1.
Enter your choice: 2
The buffer is empty! New data cannot be consumed!
Enter your choice: 1
Producer produces item number: 1
PROGRAM 4:
Develop a C program which demonstrates interprocess communication between a reader
process and a writer process. Use mkfifo, open, read, write and close APIs in your program
In computing, a named pipe (also known as a FIFO) is one of the methods for inter-process
communication.
It is an extension to the traditional pipe concept on Unix. A traditional pipe is “unnamed” and lasts
only as long as the process.
A named pipe, however, can last as long as the system is up, beyond the life of the process. It can
be deleted if no longer used.
Usually a named pipe appears as a file and generally processes attach to it for inter-process
communication. A FIFO file is a special kind of file on the local storage which allows two or more
processes to communicate with each other by reading/writing to/from this file.
FIFO special file is entered into the filesystem by calling mkfifo() in C. Once we have created a
FIFO special file in this way, any process can open it for reading or writing, in the same way as an
ordinary file. However, it has to be open at both ends simultaneously before you can proceed to do
any input or output operations on it.
Creating a FIFO file: In order to create a FIFO file, a function calls i.e. mkfifo is used.
int mkfifo(const char *pathname, mode_t mode);
mkfifo() makes a FIFO special file with name pathname. Here mode specifies the FIFO’s
permissions. It is modified by the process’s umask in the usual way: the permissions of the created
file are (mode & ~umask).
Using FIFO: As named pipe(FIFO) is a kind of file, we can use all the system calls associated with it
i.e. open, read, write, close.
Example Programs to illustrate the named pipe: There are two programs that use the same FIFO.
Program 1 writes first, then reads. The program 2 reads first, then writes. They both keep doing it
until terminated.
PROGRAM 5:
Develop a C program to simulate Bankers Algorithm for DeadLock Avoidance.
DEAD LOCK AVOIDANCE
AIM: Simulate bankers algorithm for Dead Lock Avoidance (Banker‘s Algorithm)
DESCRIPTION:
Deadlock is a situation where in two or more competing actions are waiting f or the other to finish,
and thus neither ever does. When a new process enters a system, it must declare the maximum
number of instances of each resource type it needed. This number may exceed the total number of
resources in the system.
When the user request a set of resources, the system must determine whether the allocation of
each resources will leave the system in safe state. If it will the resources are allocation; otherwise the
process must wait until some other process release the resources.
Data structures Allocation:
If Allocation [i, j]=k, Pi allocated to k instances of resource Rj Need: If
Need[I, j]=k, Pi may need k more instances of resource type Rj, Need[I, j]=Max[I, j]-Allocation[I, j];
Safety Algorithm
Work and Finish be the vector of length m and n respectively,
Work=Available and Finish[i] =False.
ALGORITHM:
SOURCE CODE:
#include<stdio.h>
#include<conio.h>
void main()
{
int work[5],avl[5],alloc[10][10],l;
int need[10][10],n,m,I,j,avail[10],max[10][10],k,count,i,fcount=0,pr[10];
char finish[10]={'f','f','f','f','f','f','f','f','f','f'};
printf("\n enter the no of process");
scanf("%d",&n);
printf("\n enter the no of resources");
scanf("%d",&m);
printf("\n enter the total no of resources");
for(i=1;i<=m;i++)
scanf("%d",&avail[i]);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&max[i][j]);
printf("\n process allocation matrix");
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&alloc[i][j]);
for(i=1;i<=n;i++) for(j=1;j<=m;j+
+) need[i][j]=max[i][j]-alloc[i][j];
for(i=1;i<=n;i++)
{ k=
0;
for(j=1;j<=m;j++)
PROGRAM 6
DESCRIPTION
One of the simplest methods for memory allocation is to divide memory into several fixed-sized
partitions. Each partition may contain exactly one process. In this multiple-partition method, when a
partition is free, a process is selected from the input queue and is loaded into the free partition. When
the process terminates, the partition becomes available for another process. The operating system keeps
a table indicating which parts of memory are available and which are occupied. Finally, when a process
arrives and needs memory, a memory section large enough for this process is provided. When it is time
to load or swap a process into main memory, and if there is more than one free block of memory of
sufficient size, then the operating system must decide which free block to allocate. Best-fit strategy
chooses the block that is closest in size to the request.
First-Fit
This is a very basic strategy in which we start from the beginning and allot the first hole, which is big
enough as per the requirements of the process. The first-fit strategy can also be implemented in a way
where we can start our search for the first-fit hole from the place we left off last time.
Best-Fit
This is a greedy strategy that aims to reduce any memory wasted because of internal fragmentation in
the case of static partitioning, and hence we allot that hole to the process, which is the smallest hole that
fits the requirements of the process. Hence, we need to first sort the holes according to their sizes and
pick the best fit for the process without wasting memory.
Worst-Fit
This strategy is the opposite of the Best-Fit strategy. We sort the holes according to their sizes and
choose the largest hole to be allotted to the incoming process. The idea behind this allocation is that as
the process is allotted a large hole, it will have a lot of space left behind as internal fragmentation.
Hence, this will create a hole that will be large enough to accommodate a few other processes.
int frag[max],b[max],f[max],i,j,nb,nf,t
emp; static int bf[max],ff[max];
printf("\n\tMemory Management Scheme - First Fit"); printf("\
nEnter the number of blocks:");
scanf("%d",&nb);
printf("Enter the number of files:");
scanf("%d",&nf);
printf("Block %d:",i);
scanf("%d",&b[i]);
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)
ff[i]=j;
break;
frag[i]=temp;
bf[ff[i]]=1;
}
printf("\nFile_no:\tFile_size :\tBlock_no:\tBlock_size:\tFragement");
for(i=1;i<=nf;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]);
}
OUT PUT
$ cc mm.c
$ ./a.out
Block 2: 2
Block 3: 7
File 2: 4
OUTPUT
1 1 1 5 4
2 4 3 7 3
Program :BEST-FIT
#include<stdio.h>
#define max 25
void 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("\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
$ cc best.c
$./a.out
Block 2: 2
Block 3: 7
OUTPUT
2 4 1 5 1
Program :FIRST-FIT
#include<stdio.h>
#define max 25
void main()
{
int frag[max],b[max],f[max],i,j,nb,nf,temp,highes t=0;
static int bf[max],ff[max];
printf("\n\tMemory Management Scheme - Worst Fit"); 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("File %d:",i);
scanf("%d",&f[i]);
for(i=1;i<=nf;i++)
for(j=1;j<=nb;j++)
temp=b[j]-f[i];
if(temp>=0)
if(highest<temp)
ff[i]=j; highest=temp;
printf("\nFile_no:\tFile_size:\tBlock_no:\tBlock_size:\tFragement");
for(i=1;i<=nf;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
$ CC first.c
$./a.out
Block 2: 2
Block 3: 7
OUTPUT
1 1 3 7 6
2 4 1 5 1
PROGRAM 7:
a) FIFO
b) LRU
DESCRIPTION:
Page replacement algorithms are an important part of virtual memory management and it helps the OS
to decide which memory page can be moved out making space for the currently needed page. However,
the ultimate objective of all page replacement algorithms is to reduce the number of page faults.
FIFO-This is the simplest page replacement algorithm. In this algorithm, the operating system keeps
track of all pages in the memory in a queue, the oldest page is in the front of the queue. When a page
needs to be replaced page in the front of the queue is selected for removal.
LRU-In this algorithm page will be replaced which is least recently used
ALGORITHM:
1. Start the process
6. Replace the page with circular queue, while re-placing check page availability in the frame Place
void display();
int i,j,page[12]={2,3,2,1,5,2,4,5,3,2,5,2};
int flag1=0,flag2=0,pf=0,frsize=3,top=0;
for(i=0;i<3;i++)
{
fr[i]=-1;
for(j=0;j<12;j++)
{
flag1=0; flag2=0;
for(i=0;i<12;i++)
{
if(fr[i]==page[j])
flag1=1; flag2=1;
break;
}}
if(flag1==0)
for(i=0;i<frsize;i++)
fr[i]=page[j]; flag2=1;
break;
if(flag2==0)
fr[top]=page[j];
top++;
pf++;
if(top>=frsize)
top=0;
display();
void display()
int i; printf("\n");
for(i=0;i<3;i++)
printf("%d\t",fr[i]);
}
$ ./a.out 2
-1 -1
2 3 -1
2 3 -1
2 3 1
5 3 1
5 2 1
5 2 4
5 2 4
3 2 4
3 2 4
3 5 4
3 5 2
SOURCE CODE :
int fr[3];
void main()
void display();
int p[12]={2,3,2,1,5,2,4,5,3,2,5,2},i,j,fs[3];
int index,k,l,flag1=0,flag2=0,pf=0,frsize=3;
for(i=0;i<3;i++)
{
fr[i]=-1;
for(j=0;j<12;j++)
flag1=0,flag2=0;
for(i=0;i<3;i++)
if(fr[i]==p[j])
flag1=1; flag2=1;
break;
}
if(flag1==0)
for(i=0;i<3;i++)
if(fr[i]==-1)
fr[i]=p[j]; flag2=1;
break;
}
if(flag2==0)
for(i=0;i<3;i++)
fs[i]=0;
for(k=j-1,l=1;
l<=frsize-1;
l++,k--)
for(i=0;i<3;i++)
if(fr[i]==p[k])
fs[i]=1;
}}
for(i=0;i<3;i++)
if(fs[i]==0)
index=i;
fr[index]=p[j];
pf++;
}
DEPT OF CSE-AI & ML, ATMECE, MYSURU
74
OPERATING SYSTEM LABORATORY BCS303
display();
void display()
int i; printf("\n");
for(i=0;i<3;i++)
printf("\t%d",fr[i]);
}
OUTPUT:
2 -1 -1
2 3 -1
2 3 -1
2 3 1
2 5 1
2 5 1
2 5 4
2 5 4
3 5 4
3 5 2
3 5 2
3 5 2
No of page faults: 7
LRU
AIM: To Simulate LRU page replacement algorithms.
ALGORITHM:
Step 1: Start the program.
Step 6: Allocate the pages in to frames by selecting the page that has not been used for the longest
period of time.
Step 7: Display the number of page faults. Step 8: Stop the program.
PROGRAM :
SOURCE CODE: /* A program to simulate LRU Page Replacement Algorithm */
#include<stdio.h>
Int main()
{
int a[5],b[20],p=0,q=0,m=0,h,k,i,q1=1,j,u,n; char f='F';
printf("Enter the number of pages:");
scanf("%d",&n);
printf("Enter %d Page Numbers:",n);
for(i=0;i<n;i++)
scanf("%d",&b[i]);
for(i=0;i<n;i++)
{
if(p==0)
{
if(q>=3)
q=0;
a[q]=b[i];
if(q1<3) { q1=q; }
}
printf("\n%d",b[i]);
printf("\t");
for(h=0;h<q1;h++)
printf("%d",a[h]);
if((p==0)&&(q<=3))
{
printf("-->%c",f);
m++;
}
p=0;
if(q1==3)
{
for(k=0;k<q1;k++)
{
if(b[i+1]==a[k]) p=1;
}
for(j=0;j<q1;j++)
OUTPUT:
$ cc lru.c
$ ./a.out
2 2-->F
3 23-->F
2 23
1 231-->F
5 531-->F
2 521-->F
4 524-->F
5 524
3 324-->F
2 324
5 354-->F
2 352-->F
No of faults: 7
PROGRAM 8
DESCRIPTION: The directory structure is the organization of files into a hierarchy of folders. In a
single-level directory system, all the files are placed in one directory. There is a root directory which
has all files. It has a simple architecture and there are no sub directories. Advantage of single level
directory system is that it is easy to find a file in the directory.
SOURCE CODE :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct
{
char dname[10],f
name[10][10]; int
fcnt; }dir; void
main()
{
int i,ch;
char f[30];
dir.fcnt = 0;
printf("\nEnter name of directory -- ");
scanf("%s", dir.dname);
while(1)
{
printf("\n\n1.CreateFile\t2.DeleteFile\t3.SearchFile\n4.DisplayFiles\t5. Exit\nEnter your choice -- ");
break;
case 4:
if(dir.fcnt==0) printf("\
nDirectory Empty");
else
{
break;
default: exit(0);
OUTPUT:
$cc f1.c
$./a.out
Enter name of directory -- CSE
1. Create File
2. Delete File
3. Search File
4. Display Files
4. Display Files
1. Create File
2. Delete File
3. Search File
4. Display Files
4. Display Files 5.
1. Create File
2. Delete File
3. Search File
4. Display Files
1. Create File
2. Delete File
3. Search File
4. Display Files
1. Create File
2. Delete File
3. Search File
4. Display Files
SOURCE CODE :
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct
char dname[10],fname[10][10];
int fcnt;
dir[10];
void main()
{
int i,ch,dcnt,k;
while(1)
switch(ch)
case 1:
printf("Directory created");
break;
case 2:
printf("\nEnter name of the directory -- ");
scanf("%s",d);
for(i=0;i<dcnt;i++)
if(strcmp(d,dir[i].dname)==0)
if(i==dcnt)
printf("Directory %s not found",d);
break;
case 3:
if(strcmp(d,dir[i].dname)==0)
if(strcmp(f, dir[i].fname[k])==0)
goto jmp;
}
printf("Directory %s not found",d);
jmp : break;
case 4: printf("\nEnter name of the directory -- ");
scanf("%s",d);
for(i=0;i<dcnt;i++)
if(strcmp(d,dir[i].dname)==0)
for(k=0;
k<dir[i].fcnt;k++)
if(strcmp(f, dir[i].fname[k])==0)
goto jmp1;
goto jmp1;
break;
case 5:
if(dcnt==0)
printf("\nNo Directory's ");
else
printf("\nDirectory\tFiles");
DEPT OF CSE-AI & ML, ATMECE, MYSURU
89
OPERATING SYSTEM LABORATORY BCS303
for(i=0;i<dcnt;i++)
printf("\n%s\t\t",dir[i].dname);
for(k=0;k<dir[i].fcnt;k++)
printf("\t%s",dir[i].fname[k]);
break;
default:exit(0);
OUTPUT
$ cc f2.c
$./a.out
1. Create Directory
2. Create File
3. Delete File
4. Search File
5. Display
1. Create Directory
2. Create File
3. Delete File
4. Search File
5. Display
1. Create Directory
2. Create File
3. Delete File
4. Search File
5. Display
4. Search File
5. Display 6.
1. Create Directory
2. Create File
3. Delete File
4. Search File
5. Display
VIVA QUESTIONS
1. Define directory?
2. List the different types of directory structures?
3. What is the advantage of hierarchical directory structure?
4. Which of the directory structures is efficient? Why?
5. What is acyclic graph directory?
PROGRAM 9
A. SEQUENTIAL:
AIM: C program for implementing sequential file allocation method.
DESCRIPTION
The most common form of file structure is the sequential file in this type of file, a fixed format is used for records.
All records (of the system) have the same length, consisting of the same
number of fixed length fields in a particular order because the length and position of each field are
known, only the values of fields need to be stored, the field name and length for each field are attributes
of the file structure.
ALGORITHM:
Step 1: Start the program.
a) Check whether the required locations are free from the selected
location. if(b[s1].flag==0)
{
for (j=s1;j<s1+p[i];j++)
if((b[j].flag)==0)
count++;
if(count==p[i])
break;
}
for(s=s1;s<(s1+p[i]);s++)
k[i][j]=s;
j=j+1;
b[s].bno=s;
b[s].flag=1;
SOURCE CODE :
#include<stdio.h>
Int main()
{
int f[50],i,st,j,len,c,k;
for(i=0;i<50;i++)
f[i]=0; X:
printf("\n Enter the starting block & length of file");
scanf("%d%d",&st,&len);
for(j=st;j<(st+len);j++)
if(f[j]==0)
{ f[j]=1
;
printf("\n%d->%d",j,f[j]);
else
if(j==(st+len))
OUTPUT:
5->1
6->1
7->1
8->1
9->1
10->1
11->1
12->1
13->1
B. INDEXED
DESCRIPTION:
In the chained method file allocation table contains a field which points to starting block of memory.
From it for each bloc a pointer is kept to next successive block. Hence, there is no external
fragmentation.
ALGORITHM:
locations. q=random(100);
if(b[q].flag==0)
b[q].flag=1;
b[q].fno=j;
r[i][j]=q;
SOURCE CODE :
#include<stdio.h>
int f[50],i,k,j,inde[50],n,c,count=0,p;
main()
for(i=0;i<50;i++)
f[i]=0;
scanf("%d",&p);
if(f[p]==0)
{ f[p]=1
scanf("%d",&n);
else
for(i=0;i<n;i++)
scanf("%d",&inde[i]);
for(i=0;i<n;i++)
if(f[inde[i]]==1)
for(j=0;j<n;j++)
f[inde[j]]=1; printf("\n
allocated");
for(k=0;k<n;k++)
printf("\n %d->%d:%d",p,inde[k],f[inde[k]]);
scanf("%d",&c);
if(c==1)
goto x;
else
exit();
OUTPUT:
$ CC index.c
$ ./a.out
enter index block 9
Enter no of files on index 3 1 2 3
Allocated File
indexed 9-
>1:1
9->2;1
9->3:1 enter 1 to enter more files and 0 to exit
C) LINKED:
DESCRIPTION: In the chained method file allocation table contains a field which points to
starting block of memory. From it for each bloc a pointer is kept to next successive block. Hence,
there is no external fragmentation
ALGORTHIM:
Step 1: Start the program.
b) If the location is free allocate and set flag=1 to the allocated locations.
While allocating next location address to attach it to previous location
for(i=0;i<n;i++)
{
for(j=0;j<s[i];j++)
{
q=random(100); if(b[q].flag==0)
b[q].flag=1;
b[q].fno=j;
r[i][j]=q;
if(j>0)
{
p=r[i][j-1]; b[p].next=q;}
SOURCE CODE :
#include<stdio.h>
main()
{
int f[50],p,i,j,k,a,st,len,n,c;
for(i=0;i<50;i++)
f[i]=0;
printf("Enter how many blocks that are already allocated");
scanf("%d",&p);
printf("\nEnter the blocks no.s that are already allocated");
for(i=0;i<p;i++)
{
scanf("%d",&a);
f[a]=1;
}
X:
printf("Enter the starting index block & length");
scanf("%d%d",&st,&len);
k=len;
for(j=st;j<(k+st);j++)
{
if(f[j]==0)
{
f[j]=1;
printf("\n%d->%d",j,f[j]);
}
else
{
printf("\n %d->file is already allocated",j);
k++;
}
}
printf("\n If u want to enter onemore file? (yes-1/no-0)");
scanf("%d",&c);
if(c==1)
goto X;
else
exit();
}
OUTPUT:
Enter how many blocks that are already allocated 3
VIVA QUESTIONS
1) List the various types of files
2) What are the various file allocation strategies?
3) What is linked allocation?
4) What are the advantages of linked allocation?
5) What are the disadvantages of sequential allocation methods?
PROGRAM 10:
DESCRIPTION
One of the responsibilities of the operating system is to use the hardware efficiently. For the disk
drives, meeting this responsibility entails having fast access time and large disk bandwidth. Both the
access time and the bandwidth can be improved by managing the order in which disk I/O requests are
serviced which is called as disk scheduling. 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. In the SCAN algorithm, The disk arm starts at one end, and moves towards
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. C-SCAN is a variant of SCAN designed to provide
a 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
SOURCE CODE
#include<stdio.h>
main()
{
int t[20], d[20], h, i, j, n, temp, k, atr[20], tot, p, sum=0;
printf("enter the no of tracks to be traveresed");
scanf("%d'",&n);
printf("enter the position of head");
scanf("%d",&h);
t[0]=0;t[1]=h;
printf("enter the tracks");
for(i=2;i<n+2;i++)
scanf("%d",&t[i]);
for(i=0;i<n+2;i++)
{
for(j=0;j<(n+2)-i-1;j++)
{
if(t[j]>t[j+1])
{
temp=t[j];
t[j]=t[j+1];
t[j+1]=temp;
}}}
for(i=0;i<n+2;i++)
if(t[i]==h)
j=i;k=i;
p=0;
while(t[j]!=0)
{
atr[p]=t[j]; j--;
p++;
}
atr[p]=t[j]; for(p=k+1;p<n+2;p+
+,k++) atr[p]=t[k+1];
for(j=0;j<n+1;j++)
{
if(atr[j]>atr[j+1])
d[j]=atr[j]-atr[j+1];
else
d[j]=atr[j+1]-atr[j];
sum+=d[j];
}
printf("\nAverage header movements:%f",(float)sum/n);
}
INPUT
Enter no.of tracks: 9
OUTPUT
150 50
160 10
184 24
90 94
70 20
60 10
58 2
55 3
18 37