Master Record Os Lab r2021 Second Year
Master Record Os Lab r2021 Second Year
MASTER RECORD
(Regulation – 2021)
Prepared by
INSTITUTE VISION
INSTITUTE MISSION
➢ Developing, nurturing and building professionals with technical, research and managerial
expertise, intellectual proficiency, right attitude and moral ethics.
➢ Building infrastructure that earmarks the institution to be the most preferred educational
destination and provides the right ambience for creative and innovative teaching - learning
process.
➢ Enabling learners to broaden their horizon and helping to meet global challenges.
To provide quality education to the students and impart IT excellence by building strong
academic environment and to enable the essential skills in the innovators and entrepreneurs
making them as proficient professionals for industrial consultancy.
CYCLE – I:
1. Installation of windows operating system
2. Illustrate UNIX commands and Shell Programming
3. Process Management using System Calls : Fork, Exit, Getpid, Wait, Close
4. Write C programs to implement the various CPU Scheduling Algorithms
CYCLE – II:
5. Illustrate the inter process communication strategy
6. Implement mutual exclusion by Semaphore
7. Write C programs to avoid Deadlock using Banker’s Algorithm
8. Write a C program to Implement Deadlock Detection Algorithm
9. Write C program to implement Threading
10. Implement the paging Technique using C program
11. Write C programs to implement the following Memory Allocation Methods
a. First Fit b. Worst Fit c. Best Fit
CYCLE – III:
12. Write C programs to implement the various Page Replacement Algorithms
13. Write C programs to Implement the various File Organization Techniques
14. Implement the following File Allocation Strategies using C programs
a. Sequential b. Indexed c. Linked
15. Write C programs for the implementation of various disk scheduling algorithms
16. Install any guest operating system like Linux using VMware.
Turn off the computer that you want to install Windows on then turn it back on. When the BIOS
screen appears or you are prompted to do so, press Del, Esc, F2, F10, or F9 (depending on your
computer’s motherboard) to enter the system BIOS. The key to enter the BIOS is usually shown
on the screen.
The boot options menu of your BIOS may vary in location or name from the illustration, but you
may eventually find it if you search around.
• If you can’t find the boot options menu, search the name of your BIOS (most likely
located in the BIOS menu) online for help.
STEP 3 : SELECT THE CD-ROM DRIVE AS THE FIRST BOOT DEVICE OF YOUR
COMPUTER.
Although this method may vary among computers, the boot options menu is typically a menu of
movable device names where you should set your CD-ROM drive as the first boot device.
After you have placed the disc into the disc drive, start your computer. When the computer
starts, press a key if you are asked if you would like to boot from the disc by pressing any key.
After you choose to start from the disc, Windows Setup will begin loading.
• If you are not asked to boot from the disc, you may have done something wrong. Retry
the previous steps to solve the problem.
Read over the Microsoft Software License Terms, check I accept the license terms, and
click Next.
RESULT:
Thus the installation of Windows Operating System was done successfully
Illustrate UNIX commands and Shell Programming
EX.No: 2 a BASIC COMMANDS IN LINUX
Date:
AIM:
To learn basic UNIX commands in Linux environment.
1. DATE COMMANDS:
SYNTAX : date
USES : Used to display system date and time.
OUTPUT : Thu May 4 15:52:02 IST 2021
OPTIONS:
SYNTAX : date + %m
a = Abbreviated weekday.
A = Full weekday.
b = Abbreviated month.
B = Full month.
c = Current day and time.
C = Display the century as a decimal number.
d = Day of the month.
D = Day in „mm/dd/yy‟ format
h = Abbreviated month day.
H = Display the hour.
L = Day of the year.
m = Month of the year.
M = Minute.
P = Display AM or PM
S = Seconds
T = HH:MM:SS format
u = Week of the year.
y = Display the year in 2 digit.
Y = Display the full year.
Z = Time zone.
2. CALENDER
SYNTAX : cal
USES : It displays the current month calendar.
OUTPUT :
May 2006
Su Mo Tu We Th Fr Sa
1234567
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
SYNTAX : cal 1998
USES : It displays the mentioned year calendar.
OUTPUT : It will displays the given year calendar.
SYNTAX : $cal <month> <year>
USES : It displays the calendar of reserved month of that year.
OUTPUT : It displays the calendar of reserved month of that year.
3. ECHO
SYNTAX : echo “ UNIX ”
USES : Used to display the given text.
OUTPUT : UNIX
//Typing Content in More Than One Line
SYNTAX : echo “ This command
> line exceeds
> a single line"
OUTPUT: This command
line exceeds
a single line
USES : Used to display the multiple line as we entered while executing the
command.
SYNTAX : echo This command \
> line exceeds \
> a single line.
OUTPUT : This command line exceeds a single line.
USES : The Backslash character at the end of each line (followed by pressing the
ENTER key) informs the shell that the user wants to continue the command on the
next line. It is used to display the multiple lines into single line.
4. BC
SYNTAX : bc
USES : Used to perform simple mathematical calculations. By default this command
accepts decimal numbers and also performs mathematical calculations on octal and
hexadecimal numbers.
OUTPUT :
1) 5+3
8
2) 1.1+2.2
3.3
3) 3.3-1.2
2.1
4) 5.6*4.1
22.9
5) 8.4/3.2
2
6) 3-1
2
7) 4*5
20
5. WHO
SYNTAX : who
USES : Used to display the login details for all users using the UNIX systems.
OUTPUT :.
student pts/1 May 4 15:50 (192.168.2.3)
student pts/11 May 4 10:47 (192.168.2.19)
root :0 May 4 14:52 (console)
6. WHO AM I
SYNTAX : who am i
USES : Used to displays the login details of the current users of the system, who
invokes the command.
7. TTY
SYNTAX : tty(tele type)
USES : It gives the file name of the terminal that you are using, tell you the device
name and the name of the terminal that you currently working in.
OUTPUT : /dev/pts/1
8. MAN
SYNTAX : man any command
USES : It offers the online help facilities and it gives all details for the particular
commands that which user can type file and the directory commands.
DIRECTORY COMMANDS
9. MAKE DIRECTORY
SYNTAX : mkdir directory name
USES : Used to create a new directory.
OUTPUT : mkdir jeeva
10. CHANGE DIRECTORY
SYNTAX : cd directory name
USES : Used to change from one working directory to another directory specified by
its argument.
OUTPUT : cd jeeva
11. REMOVE DIRECTORY
SYNTAX : rmdir
USES : Used to remove the directory.
OUTPUT : rmdir jeeva
12. PWD
SYNTAX : pwd
USES : Used to display the path that we are working.
OUTPUT : /home/student/vs
FILE & REDIRECTION COMMANDS
13. CAT
SYNTAX : cat > filename
USES : Used to create a new file & insert a content into that file. Press CTRL + D to exit
from that file.
OUTPUT :
$cat >sample
flower
jasmine
rose
Press ctrl + d
OUTPUT :
$cat sample1 cat sample2
flower ab
jasmine bc
rose d
ef
$cat sample3
flower
jasmine
rose
ab
bc
d ef
OUTPUT :
$comm n1 nithi
sridhar
vikky
vimal
OPTIONS
COMPARE COMMAND
40. SYNTAX : cmp filename1 filename2
USES : Two files are compared byte by byte and the location of the first mismatch is
echoed in the screen.
OUTPUT :
$ cmp sample1 sample5
sample1 sample5 differ: byte 7, line 1
55. *
SYNTAX: $ls *
USE : used in representing any number of characters when used in the prefix or suffix.
56. ?
SYNTAX : $ ls ?
USE : this character is use to represent one character wither in prefix or in suffix of
the filename.
SORTING COMMANDS:
57. sort :
SYNTAX : $ sort filename
USE : Sort filter arranger input from standard input in alphabetical order .
OUTPUT :
$ sort alamu
OPTIONS:
61. CHMOD
SYNTAX : $ chmod -w dirname
USE : This command is used to set the three permissions for all the three categories of
users of the file. Only the owner of the file can use it.
OUTPUT:
$ chmod 777 sample
$ ls –l sample
Total 8
drwx rwx rwx 2 linux 4096 jun 24 14.46 sample
CP COMMAND:
67. vi EDITOR
The vi editor is a visual editor used to create and edit text, files, documents and
programs. It displays the content of files on the screen and allows a user to add, delete
or change part of text. There are three modes available in the vi editor, they are
1. Command mode 2. Input (or) insert mode.
Starting vi : The vi editor is invoked by giving the following commands in UNIX
prompt.
SYNTAX : $ vi <filename> (or) $vi
USE: This command would open a display screen with 25 lines and with tilt (~)
symbol at the start of each line. The first syntax would save the file in the filename
mentioned and for the next the filename must be mentioned at the end.
Options :
1. vi +n <filename> - this would point at the nth line (cursor pos).
2. vi –n <filename> - This command is to make the file to read only to change from
one mode to another press escape key.
68. INSERTING AND REPLACING COMMANDS
To move editor from command node to edit mode, you have to press the <ESC> key.
For inserting and replacing the following commands are used.
SYNTAX : ESC a
USE: This command is used to move the edit mode and start to append after the
current character.
SYNTAX : ESC A
USE : This command is also used to append the file , but this command append at the
end of current line.
SYNTAX : ESC j
USE : This command is used to move down a single line or a number of lines.
SYNTAX : ESC nj
USE: N times down movement.
SYNTAX : ESC k
USE: This command is used to move up a single line or a number of lines.
SYNTAX : ESC enter or ESC n enter
USE : This command will move the cursor to the starting of next lines or a group of
lines mentioned.
SYNTAX : ESC + ESC n+
USE : This command is used to move to the beginning of the next line.
SYNTAX : ESC 0
USE: This command will bring the cursor to the beginning of the same current line.
SYNTAX : ESC :
USE: This command will bring the cursor to the end of the current line.
SYNTAX : ESC ^ :
USE: This command is used to move to first character of first lines.
SYNTAX : ESC b or ESC nb
USE: This command is used to move back to the previous word (or) a number of
words.
69. DELETING THE TEXT FROM vi
SYNTAX : ESC x or ESC nx
USE: To delete a character to right of current cursor positions, this command is used.
SYNTAX : ESC X or ESC nX
USE: To delete a character to left of current cursor positions, this command is used.
SYNTAX : ESC dw
USE: This command is to delete a single word or number of words to right of current
cursor position.
SYNTAX : ESC db
USE: This command is to delete a single word to the left of the current cursor
position.
SYNTAX : ESC dd
USE: This command is used to delete the current line (or) a number of lines below the
current line.
SYNTAX : ESC d$
USE: This command is used to delete the text from current cursor position to last
character of current line.
Result:
Thus the basic Linux commands was implemented successfully in the Linux environment.
Ex: No: 2b SHELL PROGRAMMING
Date:
Relational operators
-eq : check fro equality of integers
-ne : check for inequality
-gt : check if one integer is greater than the other
-lt : check if one integer is lesser than the other
-ge : check if one integer is greater than or equal to the other
-le : check if one integer is lesser than or equal to the other.
-f : check if a file is an ordinary file
-d : check if a file is a directory
-r : check if a file is readable
-w : check if a file is write able
-x : check if a file is executable
Read command
Used to read the value of the shell variable from a user.
Comment statement
# this is a text program.
2) for construct
Used to perform same set of operations on a list of values.
for variable in value1 value2 value3 ...
do
Commands
done
Ex. for k in 1 2 3 4 5
do
echo “the number is $k”
echo “the square of the number is `expr $k \* $k` “
done
3) while construct
Repeatedly executing group of commands as long as the condition is true.
while condition
do
Command list
Done
Ex.to print 3 numbers
a=1
while [$a -le 3]
do
echo $a
$a=`expr $a+1`
done
o/p. 1 2 3
4) until construct
Repeatedly executing group of commands until a condition is true.
until condition
do
Commandlist
done
Ex. to print 3 numbers
a=1
until [$a -le 3]
do
echo $a
$a=`expr $a+1`
done
o/p. 1 2 3
5) case construct:
case value in
choice1) commands;;
choice2)commands;;
....
esac
Ex. $echo “enter a value”read myval
case “$myval” in
0) echo zero;;
1) echo one;;
2) echo two;;
3) echo three;;
*) echo “invalid argument”;;
esac
Result:
Thus the basic shell programming was implemented and executed successfully.
Ex: No: 2c Shell Program to check even or odd number
Date:
Aim:
To write a program to find whether a number is even or odd.
Algorithm:
1. Read the input number.
2. Perform modular division on input number by 2.
3. If remainder is 0, print the number is even.
4. Else print number is odd.
5. Stop the program.
Program:
echo "enter the number"
read num
if [ `expr $num % 2` -eq 0 ]
then
echo "number is even"
else
echo "number is odd"
fi
Output:
$ sh evenodd.c
Enter the number: 5
Number is odd
$ sh evenodd.c
Enter the number: 200
Number is even
Result:
Thus the shell program for checking even or odd number has been executed
successfully.
Ex: No: 2d Shell Program to find greatest of three numbers
Date:
Aim:
To write a shell program to find biggest of three numbers.
Algorithm:
1. Read the three numbers from the user.
2. If A is greater than B and A is greater than C, then print A is larger.
3. Else If B is greater than C, then print C is larger.
4. Else Print C Is larger.
5. Terminate the program.
Program:
echo "Enter three numbers"
read a b c
if [ $a -gt $b ] && [ $a -gt $c ]
then
echo "A is big"
else if [ $b -gt $c ]
then
echo "B is big"
else
echo "C is big"
fi
fi
Output:
$ sh biggest.sh
Enter three numbers
10 456 300
B is big
Result:
Thus the shell program for finding biggest of three numbers has been executed
successfully.
Ex: No: 2e Shell Program to find factorial of a number
Date:
Aim:
To write a shell program to find factorial of a number.
Algorithm:
1. Read a number.
2. Initialize fact as 1.
3. Initialize i as 1.
4. While i is lesser than or equal to number, multiply the value of i and fact and
assign to fact. Now increment the value of i by 1.
5. Print the result.
6. Stop the program.
Program:
echo "Enter the number"
read n
fact=1
i=1
while [ $i -le $n ]
do
fact=`expr $i \* $fact`
i=`expr $i + 1`
done
echo "The factorial value of $n is $fact"
Output:
$ sh fact.sh
Enter the number:
5
The factorial value of 5 is 120
Result:
Thus the shell program to find factorial of a number has been executed
successfully.
Ex: No: 2f Shell Program to find Fibonacci Series
Date:
Aim:
To write a shell program to find Fibonacci series.
Algorithm:
1. Initialize n1 & n2 as 0 & 1.
2. Enter the limit for Fibonacci series. Initialize variable ‘var’ as 0.
3. Print the Fibonacci series n1 and n2.
4. While the ‘var’ value is lesser than limit-2, Calculate n3=n1+n2 and Set n1=n2
and n2=n3. Increment ‘var’ by 1 and print n2.
5. Terminate the program.
Program:
echo " ENTER THE LIMIT FOR FIBONNACI SERIES"
read lim
n1=0
n2=1
var=0
echo "FIBONACCI SERIES IS "
echo "$n1"
echo "$n2"
while [ $var -lt `expr $lim - 2` ]
do
n3=`expr $n1 + $n2 `
n1=`expr $n2 `
n2=`expr $n3 `
var=`expr $var + 1 `
echo "$n2"
done
Output:
$ sh fib.sh
ENTER THE LIMIT FOR FIBONNACI SERIES
5
FIBONACCI SERIES IS
0
1
1
2
3
Result:
Thus the shell program to find Fibonacci series of a limit has been executed
successfully.
Ex: No: 2g Shell Program to perform string comparison
Date:
Aim:
To write a shell program for comparing two strings.
Algorithm:
1. Enter into the vi editor and go to the insert mode for entering the code.
2. Read the first string.
3. Read the second string
4. Compare the two strings using if condition. If the condition satisfies, then print
those two strings are equal; else print two strings are not equal.
5. Terminate the program.
Program:
echo "Enter string1"
read str1
echo "Enter string2"
read str2
if [ $str1 = $str2 ]
then
echo "Both strings are equal"
else
echo "Strings not equal"
fi
Output:
$ sh stringcompare.sh
Enter string1
Programming
Enter string2
program
Strings not equal
$ sh stringcompare.sh
Enter string1
Shell
Enter string2
Shell
Both strings are equal
Result:
Thus the shell program to compare the two strings is executed and output is
verified successfully.
Ex: No: 2h Shell Program to perform arithmetic operations
Date:
Aim:
To write a shell program to perform the arithmetic operations using case.
Algorithm:
1. Read the input variables and assign the value.
2. Print the list of arithmetic operations to read the choices from user.
3. Using the case operator, assign the various arithmetic operators and perform
its evaluation.
4. Check the values for all the corresponding operations and display the result.
5. Stop the program.
Program:
echo "1. Addition 2. Subtraction 3. Multiply 4. Division"
echo "Enter your choice"
read a
echo "Enter the values"
read b c
case $a in
1) d=`expr $b + $c`
echo "Sum=$d"
;;
2) d=`expr $b - $c`
echo "Subtraction=$d"
;;
3) d=`expr $b \* $c`
echo "Multiply=$d"
;;
4) d=`expr $b / $c`
echo "Division=$d"
;;
*) echo "No proper choice given"
;;
esac
Output:
$ sh calc.sh
1. Addition 2. Subtraction 3. Multiply 4. Division
Enter your choice
1
Enter the values
10 34
Sum=44
$ sh calc.sh
1. Addition 2. Subtraction 3. Multiply 4. Division
Enter your choice
2
Enter the values
30 10
Subtraction=20
$ sh calc.sh
1. Addition 2. Subtraction 3. Multiply 4. Division
Enter your choice
3
Enter the values
20 45
Multiply=900
$ sh calc.sh
1. Addition 2. Subtraction 3. Multiply 4. Division
Enter your choice
4
Enter the values
200 4
Division=50
$ sh calc.sh
1. Addition 2. Subtraction 3. Multiply 4. Division
Enter your choice
Enter the values
56
No proper choice given
$ sh calc.sh
1. Addition 2. Subtraction 3. Multiply 4. Division
Enter your choice
7
Enter the values
12 34
No proper choice given
Result:
Thus the shell program to perform arithmetic operations using case is executed
and output is verified successfully .
Process Management using System Calls : Fork, Exit, Getpid, Wait, Close
Aim:
To create a new child process using fork( ) system call.
fork()
The fork system call is used to create a new process called child process.
The return value is 0 for a child process.
The return value is negative if process creation is unsuccessful.
For the parent process, return value is positive
The child process is an exact copy of the parent process.
Both the child and parent continue to execute the instructions following
fork call.
The child can start execution before the parent or vice-versa.
getpid()and getppid()
The getpid system call returns process ID of the calling process
The getppid system call returns parent process ID of the calling process
Algorithm:
1. Declare a variable x to be shared by both child and parent.
2. Create a child process using fork system call.
3. If return value is -1 then
Print "Process creation unsuccessfull"
Terminate using exit system call.
4. If return value is 0 then
Print "Child process"
Print process id of the child using getpid system
call Print value of x
Print process id of the parent using getppid system call
5. Otherwise
Print "Parent process"
Print process id of the parent using getpid
system call Print value of x
Print process id of the shell using getppid system call.
6. Stop
Program:
/* Process creation - fork.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
pid_t pid;
int x = 5;
pid = fork();
x++;
if (pid < 0)
{
printf("Process creation error");
exit(-1);
}
else if (pid == 0)
{
printf("Child process:");
printf("\n Process id is %d", getpid());
printf("\n Value of x is %d", x);
printf("\n Process id of parent is %d\n", getppid());
}
else
{
printf("\nParent process:");
printf("\nProcess id is %d", getpid());
printf("\nValue of x is %d", x);
printf("\nProcess id of shell is %d\n", getppid());
}
}
Output:
$ gcc fork.c
$ ./a.out
Child process:
Process id is 19499
Value of x is 6
Process id of parent is 19498
Parent process:
Process id is 19498
Value of x is 6
Process id of shell is 3266
Result:
Thus a child process is created with copy of its parent's address space.
Ex.No: 3b Implementation of wait( ) system call
Date:
Aim:
To block a parent process until child completes using wait system call.
wait()
The wait system call causes the parent process to be blocked until a child terminates.
When a process terminates, the kernel notifies the parent by sending the SIGCHLD signal to the
parent.
Without wait, the parent may finish first leaving a zombie child, to be adopted by init process
Algorithm:
1. Create a child process using fork system call.
2. If return value is -1 then
a. Print "Process creation unsuccessfull"
3. Terminate using exit system call.
4. If return value is > 0 then
a. Suspend parent process until child completes using wait system call
b. Print "Parent starts"
c. Print even numbers from 0–10
d. Print "Parent ends"
5. If return value is 0 then
a. Print "Child starts"
b. Print odd numbers from 0–10
c. Print "Child ends"
6. Stop
Program:
/* Wait for child termination - wait.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
main()
{
int i, status;
pid_t pid;
pid = fork();
if (pid < 0)
{
printf("\nProcess creation failure\n");
exit(-1);
}
else if(pid > 0)
{
wait(NULL);
printf ("\nParent starts\nEven Nos: ");
for (i=2;i<=10;i+=2)
printf ("%3d",i);
printf ("\nParent ends\n");
}
else if (pid == 0)
{
printf ("Child starts\nOdd Nos: ");
for (i=1;i<10;i+=2)
printf ("%3d",i);
printf ("\nChild ends\n");
}
}
Output:
$ gcc wait.c
$ ./a.out
Child starts
Odd Nos: 1 3 5 7 9
Child ends
Parent starts
Even Nos: 2 4 6 8 10
Parent ends
Result:
Thus using wait system call zombie child processes were avoided.
EX. No: 4a CPU Scheduling Algorithms- FCFS Scheduling
Date:
Aim:
To schedule snapshot of processes queued according to FCFS scheduling.
Process Scheduling:
➢ CPU scheduling is used in multi-programmed operating systems.
➢ By switching CPU among processes, efficiency of the system can be
improved.
➢ Some scheduling algorithms are FCFS, SJF, Priority, Round-Robin, etc.
➢ Gantt chart provides a way of visualizing CPU scheduling and enables to
understand better.
Algorithm:
1. Define an array of structure process with members pid, btime, wtime &
ttime.
2. Get length of the ready queue, i.e., number of process (say n)
3. Obtain btime for each process.
4. The wtime for first process is 0.
5. Compute wtime and ttime for each process as:
a. wtimei+1 = wtimei + btimei
b. ttimei = wtimei + btimei
6. Compute average waiting time awat and average turnaround time atur
7. Display the btime, ttime and wtime for each process.
8. Display GANTT chart for the above scheduling
9. Display awat time and atur
10. Stop
Program
/* FCFS Scheduling- fcfs.c */
#include <stdio.h>
struct process
{
int pid;
int btime;
int wtime;
int ttime;
} p[10];
main()
{
int i,j,k,n,ttur,twat; float
awat,atur;
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d (in ms) : ",(i+1));
scanf("%d", &p[i].btime);
p[i].pid = i+1;
}
p[0].wtime = 0;
for(i=0; i<n; i++)
{
p[i+1].wtime = p[i].wtime + p[i].btime;
p[i].ttime = p[i].wtime + p[i].btime;
}
ttur = twat = 0;
for(i=0; i<n; i++)
{
ttur += p[i].ttime;
twat += p[i].wtime;
}
awat = (float)twat / n;
atur = (float)ttur / n;
FCFS Scheduling
P1 10 10 0
P2 4 14 10
P3 11 25 14
P4 6 31 25
GANTT Chart
| P1 | P2 | P3 | P4 |
0 10 14 25 31
Result:
Thus waiting time & turnaround time for processes based on FCFS
scheduling was computed and the average waiting time was determined.
Ex. No: 4 b SJF Scheduling
Date:
Aim:
To schedule snapshot of processes queued according to SJF scheduling.
Algorithm:
1. Define an array of structure process with members pid, btime, wtime &
ttime.
2. Get length of the ready queue, i.e., number of process (say n)
3. Obtain btime for each process.
4. Sort the processes according to their btime in ascending order.
a. If two process have same btime, then FCFS is used to resolve the tie.
5. The wtime for first process is 0.
6. Compute wtime and ttime for each process as:
a. wtimei+1 = wtimei + btimei
b. ttimei = wtimei + btimei
7. Compute average waiting time awat and average turn around time atur.
8. Display btime, ttime and wtime for each process.
9. Display GANTT chart for the above scheduling.
10. Display awat and atur.
11. Stop.
Program:
/* SJF Scheduling – sjf.c */
#include <stdio.h>
struct process
{
int pid;
int btime;
int wtime;
int ttime;
} p[10], temp;
main()
{
int i,j,k,n,ttur,twat;
float awat,atur;
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d (in ms) : ",(i+1));
scanf("%d", &p[i].btime);
p[i].pid = i+1;
}
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if((p[i].btime > p[j].btime) ||(p[i].btime == p[j].btime && p[i].pid > p[j].pid))
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
p[0].wtime = 0;
for(i=0; i<n; i++)
{
p[i+1].wtime = p[i].wtime + p[i].btime;
p[i].ttime = p[i].wtime + p[i].btime;
}
ttur = twat = 0;
for(i=0; i<n; i++)
{
ttur += p[i].ttime;
twat += p[i].wtime;
}
awat = (float)twat / n;
atur = (float)ttur / n;
printf("\n SJF Scheduling\n\n");
for(i=0; i<28; i++)
printf("-");
printf("\n Process B-Time T-Time W-Time\n");
for(i=0; i<28; i++)
printf("-");
for(i=0; i<n; i++)
printf("\n P%-4d\t%4d\t%3d\t%2d", p[i].pid,p[i].btime,p[i].ttime,p[i].wtime);
printf("\n");
for(i=0; i<28; i++)
printf("-");
printf("\n\n Average waiting time: %5.2fms", awat);
printf("\n Average turn around time : %5.2fms\n", atur);
printf("\n\n GANTT Chart\n");
printf("-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n|");
for(i=0; i<n; i++)
{
k = p[i].btime/2;
for(j=0; j<k; j++)
printf(" ");
printf("P%d",p[i].pid);
for(j=k+1; j<p[i].btime;j++)
printf(" ");
printf("|");
}
printf("\n-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n0");
for(i=0; i<n; i++)
{
for(j=0; j<p[i].btime; j++)
printf(" ");
printf("%2d",p[i].ttime);
}
}
Output:
$ cc sjf.c
$./a.out
Enter no. of process :5
Burst time for process P1 (in ms) : 10
Burst time for process P2 (in ms) : 6
Burst time for process P3 (in ms) : 5
Burst time for process P4 (in ms) : 6
Burst time for process P5 (in ms) : 9
SJF Scheduling
P3 5 5 0
P2 6 11 5
P4 6 17 11
P5 9 26 17
P1 10 36 26
GANTT Chart
| P3 | P2 | P4 | P5 | P1 |
0 5 11 17 26 36
Result:
Thus waiting time & turnaround time for processes based on SJF
scheduling was computed and the average waiting time was determined.
Ex. No: 4c PriorityScheduling
Date:
Aim:
To schedule snapshot of processes queued according to Priority scheduling.
Priority:
➢ Process that has higher priority is processed first.
➢ Priority can be preemptive or non–preemptive.
➢ When two processes have same priority, FCFS is used to break the tie.
➢ Can result in starvation, since low priority processes may not be processed.
Algorithm:
1. Define an array of structure process with members pid, btime, pri, wtime &
ttime.
2. Get length of the ready queue, i.e., number of process (say n)
3. Obtain btime and pri for each process.
4. Sort the processes according to their pri in ascending order.
a. If two process have same pri, then FCFS is used to resolve the tie.
5. The wtime for first process is 0.
6. Compute wtime and ttime for each process as:
a. wtimei+1 = wtimei + btimei
b. ttimei = wtimei + btimei
7. Compute average waiting time awat and average turn around time atur
8. Display the btime, pri, ttime and wtime for each process.
9. Display GANTT chart for the above scheduling
10. Display awat and atur
11. Stop
Program:
/* Priority Scheduling- priority.c */
#include <stdio.h>
struct process
{
int pid; int
btime; int
pri; int
wtime; int
ttime;
} p[10], temp;
main()
{
int i,j,k,n,ttur,twat;
float awat,atur;
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d (in ms) : ", (i+1));
scanf("%d", &p[i].btime);
printf("Priority for process P%d : ", (i+1));
scanf("%d", &p[i].pri);
p[i].pid = i+1;
}
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if((p[i].pri > p[j].pri) ||(p[i].pri == p[j].pri && p[i].pid > p[j].pid))
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
p[0].wtime = 0;
for(i=0; i<n; i++)
{
p[i+1].wtime = p[i].wtime + p[i].btime;
p[i].ttime = p[i].wtime + p[i].btime;
}
ttur = twat = 0;
for(i=0; i<n; i++)
{ttur += p[i].ttime;
twat += p[i].wtime;
}
awat = (float)twat / n;
atur = (float)ttur / n;
printf("\n\t Priority Scheduling\n\n");
for(i=0; i<38; i++)
printf("-");
printf("\nProcess B-Time Priority T-Time W-Time\n");
for(i=0; i<38; i++)
printf("-");
for (i=0; i<n; i++)
printf("\nP%4d\t%4d\t%3d\t%4d\t%4d",p[i].pid,p[i].btime,p[i].pri,p[i].ttime,
p[i].wtime);
printf("\n");
for(i=0; i<38; i++)
printf("-");
printf("\n\nAverage waiting time: %5.2fms", awat);
printf("\nAverage turn around time : %5.2fms\n", atur);
printf("\n\nGANTT Chart\n");
printf("-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n|");
for(i=0; i<n; i++)
{
k = p[i].btime/2;
for(j=0; j<k; j++)
printf(" ");
printf("P%d",p[i].pid);
for(j=k+1; j<p[i].btime; j++)
printf(" ");
printf("|");
}
printf("\n-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n0");
for(i=0; i<n; i++)
{
for(j=0; j<p[i].btime; j++)
printf(" ");
printf("%2d",p[i].ttime);
}
}
Output:
$ cc priority.c
$./a.out
Enter no. of process : 5
Burst time for process P1 (in ms) : 10
Priority for process P1 : 3
Burst time for process P2 (in ms) : 7
Priority for process P2 : 1
Burst time for process P3 (in ms) : 6
Priority for process P3 : 3
Burst time for process P4 (in ms) : 13
Priority for process P4 : 4
Burst time for process P5 (in ms) : 5
Priority for process P5 : 2
Priority Scheduling
P2 7 1 7 0
P5 5 2 12 7
P1 10 3 22 12
P3 6 3 28 22
P4 13 4 41 28
Average waiting time: 13.80ms Average
turnaround time: 22.00ms
GANTT Chart
| P2 | P5 | P1 | P3 | P4 |
0 7 12 22 28 41
Result:
Thus waiting time & turnaround time for processes based on Priority
scheduling was computed and the average waiting time was determined.
Ex. No: 4d Round Robin Scheduling
Date:
Aim:
To schedule snapshot of processes queued according to Round robin scheduling.
Round Robin:
➢ All processes are processed one by one as they have arrived, but in rounds.
➢ Each process cannot take more than the time slice per round.
➢ Round robin is a fair preemptive scheduling algorithm.
➢ A process that is yet to complete in a round is preempted after the time
slice and put at the end of the queue.
➢ When a process is completely processed, it is removed from the queue.
Algorithm
1. Get length of the ready queue, i.e., number of process (say n)
2. Obtain Burst time Bi for each processes Pi.
3. Get the time slice per round, say TS.
4. Determine the number of rounds for each process.
5. The wait time for first process is 0.
6. If Bi > TS then process takes more than one round. Therefore turnaround
and waiting time should include the time spent for other remaining
processes in the same round.
7. Calculate average waiting time and turnaround time
8. Display the GANTT chart that includes,
a. Order in which the processes were processed in progression of rounds.
b. Turnaround time Ti for each process in progression of rounds.
9. Display the burst time, turnaround time and wait time for each process (in
order of rounds they were processed).
10. Display average wait time and turnaround time.
11. Stop.
Program:
/* Round robin scheduling- rr.c */
#include <stdio.h>
main()
{
int i,x=-1,k[10],m=0,n,t,s=0;
int a[50],temp,b[50],p[10],bur[10],bur1[10];
int wat[10],tur[10],ttur=0,twat=0,j=0;
float awat,atur;
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d : ", (i+1));
scanf("%d", &bur[i]);
bur1[i] = bur[i];
}
printf("Enter the time slice (in ms) : ");
scanf("%d", &t);
for(i=0; i<n; i++)
{
b[i] = bur[i] / t;
if((bur[i]%t) != 0)
b[i] += 1;
m += b[i];
}
printf("\n\t\tRound Robin Scheduling\n");
printf("\nGANTT Chart\n");
for(i=0; i<m; i++)
printf(" ---------------------- ");
printf("\n");
a[0] = 0;
while(j < m)
{
if(x == n-1)
x = 0;
else
x++;
if(bur[x] >= t)
{
bur[x] -= t;
a[j+1] = a[j] + t;
if(b[x] == 1)
{
p[s] = x;
} k[s] = a[j+1]; s++;
j++;
b[x] -= 1;
printf("P%d|", x+1);
}
else if(bur[x] != 0)
{
a[j+1] = a[j] + bur[x];
bur[x] = 0;
if(b[x] == 1)
{
p[s] = x;
k[s] = a[j+1];
s++;
}
j++;
b[x] -= 1;
printf("P%d|",x+1);
}
}
printf("\n");
for(i=0;i<m;i++)
printf(" ----------------------------- ");
printf("\n");
for(j=0; j<=m; j++)
printf("%d\t", a[j]);
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
if(p[i] > p[j])
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
temp = k[i];
k[i] = k[j];
k[j] = temp;
}
}
}
for(i=0; i<n; i++)
{
wat[i] = k[i] - bur1[i];
tur[i] = k[i];
}
for(i=0; i<n; i++)
{
ttur += tur[i];
twat += wat[i];
}
printf("\n\n");
for(i=0; i<30; i++)
printf("-");
printf("\nProcess\tBurst\tTrnd\tWait\n");
for(i=0; i<30; i++)
printf("-");
for (i=0; i<n; i++)
printf("\nP%-4d\t%4d\t%4d\t%4d", p[i]+1, bur1[i], tur[i],wat[i]);
printf("\n");
for(i=0; i<30; i++)
printf("-");
awat = (float)twat / n;
atur = (float)ttur / n;
printf("\n\nAverage waiting time: %.2f ms", awat);
printf("\nAverage turnaround time : %.2f ms\n", atur);
}
Output:
Enter no. of process : 5
Burst time for process P1 : 10
Burst time for process P2 : 29
Burst time for process P3 : 3
Burst time for process P4 : 7
Burst time for process P5 : 12
Enter the time slice (in ms) : 10
0 10 20 23 30 40 50 52 61
P1 10 10 0
P2 29 61 32
P3 3 23 20
P4 7 30 23
P5 12 52 40
Result:
Thus waiting time and turnaround time for processes based on Round robin
scheduling was computed and the average waiting time was determined.
Ex. No: 5a Inter Process Communication
Date:
Aim:
To generate 25 Fibonacci numbers and determine prime amongst them using
pipe.
Pipe:
➢ Pipes are unidirectional byte streams which connect the standard output
from one process into the standard input of another process.
➢ A pipe is created using the system call pipe that returns a pair of file
descriptors.
➢ The descriptor pfd[0] is used for reading and pfd[1] is used for writing.
➢ Can be used only between parent and child processes.
Algorithm:
1. Declare a array to store Fibonacci numbers
2. Declare an array pfd with two elements for pipe descriptors.
3. Create pipe on pfd using pipe function call.
a. If return value is -1 then stop
4. Using fork system call, create a child process.
5. Let the child process generate 25 Fibonacci numbers and store them in a
array.
6. Write the array onto pipe using write systemcall.
7. Block the parent till child completes using waitsystem call.
8. Store Fibonacci nos. written by child from the pipe in an array using read
system call
9. Inspect each element of the Fibonacci array and check whether they are
prime
a. If prime then print the Fibonacci term.
10. Stop
Program:
/* Fibonacci and Prime using pipe - fibprime.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
pid_t pid;
int pfd[2];
int i,j,flg,f1,f2,f3;
static unsigned int ar[25],br[25];
if(pipe(pfd) == -1)
{printf("Error in pipe");
exit(-1);
}
pid=fork(); if
(pid == 0)
{ printf("Child process generates Fibonacci series\n" );
f1 = -1;
f2 = 1;
for(i = 0;i < 25; i++)
{f3 = f1 + f2;
printf("%d\t",f3);
f1 = f2;
f2 = f3;
ar[i] = f3;
}write(pfd[1],ar,25*sizeof(int));
}
else if (pid > 0)
{wait(NULL);
read(pfd[0], br, 25*sizeof(int));
printf("\nParent prints Fibonacci that are Prime\n");
for(i = 0;i < 25; i++)
{flg = 0;
if (br[i] <= 1)
flg = 1;
for(j=2; j<=br[i]/2; j++)
{if (br[i]%j == 0)
{flg=1; break;
}}
if (flg == 0) printf("%d\t", br[i]);
}
elseprintf("\n");}
{
printf("Process creation failed"); exit(-1);
}
}
Output:
$ cc fibprime.c
$ ./a.out
Result:
Thus generation of Fibonacci numbers that are prime is determined using IPC
pipe.
Ex. No: 5b Implementation of commands using pipes (who | wc -l )
Date:
Aim:
To determine number of users logged in using pipe.
Algorithm:
1. Declare an array pfd with two elements for pipe descriptors.
2. Create pipe on pfd using pipe function call.
a. If return value is -1 then stop
3. Using fork system call, create a child process.
4. Free the standard output (1) using close system call to redirect the output to
pipe.
5. Make a copy of write end of the pipe using dup system call.
6. Execute who command using execlp system call.
7. Free the standard input (0) using close system call in the other process.
8. Make a close of read end of the pipe using dup system call.
9. Execute wc –l command using execlp system call.
10. Stop
Program:
/* No. of users logged - cmdpipe.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int pfds[2];
pipe(pfds);
if (!fork())
{
close(1);
dup(pfds[1]);
close(pfds[0]);
} execlp("who", "who", NULL);
else
{
close(0);
dup(pfds[0]);
close(pfds[1]);
} execlp("wc", "wc", "-l", NULL);
}
Output:
$ cc cmdpipe.c
$ ./a.out
15
Result:
Thus standard output of who is connected to standard input of wc using pipe to
compute number of users logged in.
Ex. No: 5c Chat Messaging
Date:
Aim:
To exchange message between server and client using message queue.
Message Queue:
➢ A message queue is a linked list of messages stored within the kernel.
➢ A message queue is identified by a unique identifier.
➢ Every message has a positive long integer type field, a non-negative length,
and the actual data bytes.
➢ The messages need not be fetched on FCFS basis. It could be based on type
field.
Algorithm:
Server
1. Declare a structure mesgq with type and text fields.
2. Initialize key to 2013 (some random value).
3. Create a message queue using msgget with key & IPC_CREAT as parameter.
a. If message queue cannot be created then stop.
4. Initialize the message type member of mesgq to 1.
5. Do the following until user types Ctrl+D
a. Get message from the user and store it in text member.
b. Delete the newline character in text member.
c. Place message on the queue using msgsend for the client to read.
d. Retrieve the response message from the client using msgrcv function.
e. Display the text contents.
6. Remove message queue from the system using msgctl with IPC_RMID as
parameter.
7. Stop.
Client
1. Declare a structure mesgq with type and text fields.
2. Initialize key to 2013 (same value as in server).
3. Open the message queue using msgget with key as parameter.
a. If message queue cannot be opened then stop.
4. Do while the message queue exists
a. Retrieve the response message from the server using msgrcv function
b. Display the text contents.
c. Get message from the user and store it in text member.
d. Delete the newline character in text member.
e. Place message on the queue using msgsend for the server to read.
5. Print "Server Disconnected".
6. Stop
Program:
Server
/* Server chat process - srvmsg.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct mesgq
{
long type;
char text[200];
} mq;
main()
{
int msqid, len;
key_t key = 2013;
if((msqid = msgget(key, 0644|IPC_CREAT)) == -1)
{
perror("msgget");
exit(1);
}
printf("Enter text, ^D to quit:\n"); mq.type = 1;
while(fgets(mq.text, sizeof(mq.text), stdin) != NULL)
{
len = strlen(mq.text);
if (mq.text[len-1] == '\n')
mq.text[len-1] = '\0';
msgsnd(msqid, &mq, len+1, 0);
msgrcv(msqid, &mq, sizeof(mq.text), 0, 0);
printf("From Client: \"%s\"\n", mq.text);
}
msgctl(msqid, IPC_RMID, NULL);
}
Client
/* Client chat process - climsg.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct mesgq
{
long type;
char text[200];
} mq;
main()
{
int msqid, len;
key_t key = 2013;
if ((msqid = msgget(key, 0644)) == -1)
{
printf("Server not active\n");
exit(1);
}
printf("Client ready :\n");
while (msgrcv(msqid, &mq, sizeof(mq.text), 0, 0) != -1)
{
printf("From Server: \"%s\"\n", mq.text);
fgets(mq.text, sizeof(mq.text), stdin);
len = strlen(mq.text);
if (mq.text[len-1] == '\n')
mq.text[len-1] = '\0';
msgsnd(msqid, &mq, len+1, 0);
}
printf("Server Disconnected\n");
}
Output:
Server
$ cc srvmsg.c -o srvmsg
$ ./srvmsg
Enter text, ^D to quit: hi
From Client: "hello" Where r u?
From Client: "I'm where i am" bye
From Client: "ok"
^D
Client
$ cc climsg.c -o climsg
$ ./climsg
Client ready:
From Server: "hi" hello
From Server: "Where r u?" I'm where i am
From Server: "bye" ok
Server Disconnected
Result:
Thus chat session between client and server was done using message queue.
Ex. No: 5d Process Communication using Shared Memory
Date:
Aim:
To demonstrate communication between processes using shared memory.
Shared Memory:
➢ Two or more processes share a single chunk of memory to communicate
randomly.
➢ Semaphores are generally used to avoid race condition amongst processes.
➢ Fastest amongst all IPCs as it does not require any system call.
➢ It avoids copying data unnecessarily.
Algorithm:
Server
1. Initialize size of shared memory shmsize to 27.
2. Initialize key to 2013 (some random value).
3. Create a shared memory segment using shmget with key & IPC_CREAT as
parameter.
a. If shared memory identifier shmid is -1, then stop.
4. Display shmid.
5. Attach server process to the shared memory using shmmat with shmid as
parameter.
a. If pointer to the shared memory is not obtained, then stop.
6. Clear contents of the shared region using memset function.
7. Write a–z onto the shared memory.
8. Wait till client reads the shared memory contents.
9. Detatch process from the shared memory using shmdt system call.
10. Remove shared memory from the system using shmctl with IPC_RMID
argument.
11. Stop.
Client
1. Initialize size of shared memory shmsize to 27.
2. Initialize key to 2013 (same value as in server).
3. Obtain access to the same shared memory segment using same key.
a. If obtained then display the shmid else print "Server not started"
4. Attach client process to the shared memory using shmmat with shmid as
parameter.
a. If pointer to the shared memory is not obtained, then stop.
5. Read contents of shared memory and print it.
6. After reading, modify the first character of shared memory to '*'
7. Stop.
Program:
Server
/* Shared memory server - shms.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define shmsize 27
main()
{
char c;
int shmid;
key_t key =2013;
char *shm, *s;
if ((shmid = shmget(key, shmsize, IPC_CREAT|0666)) < 0)
{ perror("shmget"); exit(1);
}
printf("Shared memory id : %d\n", shmid);
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
{ perror("shmat"); exit(1);
}
memset(shm, 0, shmsize);
s = shm;
printf("Writing (a-z) onto shared memory\n");
for (c = 'a'; c <= 'z'; c++)
*s++ = c;
*s = '\0';
while (*shm != '*');
printf("Client finished reading\n");
if(shmdt(shm) != 0)
fprintf(stderr, "Could not close memory segment.\n");
shmctl(shmid, IPC_RMID, 0);
}
Client
/* Shared memory client - shmc.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define shmsize 27
main()
{
int shmid;
key_t key = 2013;
char *shm, *s;
if ((shmid = shmget(key, shmsize, 0666)) < 0)
{
printf("Server not started\n");
} exit(1);
else
printf("Accessing shared memory id : %d\n",shmid);
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
{
perror("shmat");
exit(1);
}
printf("Shared memory contents:\n");
for (s = shm; *s != '\0'; s++)
putchar(*s);
putchar('\n');
*shm = '*';
}
Output:
Server
$ cc shms.c -o shms
$ ./shms
Shared memory id : 196611
Writing (a-z) onto shared memory
Client finished reading
Client
$ cc shmc.c -o shmc
$ ./shmc
Accessing shared memory id : 196611
Shared memory contents:
abcdefghijklmnopqrstuvwxyz
Result:
Thus contents written onto shared memory by the server process is read by
the client process using shared memory technique successfully.
Ex. No: 5e Implementation of Producer-Consumer Process
Date:
Aim:
To synchronize producer and consumer processes using semaphore.
Semaphores:
➢ A semaphore is a counter used to synchronize access to a shared data
amongst multiple processes.
➢ To obtain a shared resource, the process should:
o Test the semaphore that controls the resource.
o If value is positive, it gains access and decrements value of semaphore.
o If value is zero, the process goes to sleep and awakes when value is > 0.
➢ When a process relinquishes resource, it increments the value of semaphore
by 1.
Producer-Consumer Process:
➢ A producer process produces information to be consumed by a consumer
process.
➢ A producer can produce one item while the consumer is consuming another
one.
➢ With bounded-buffer size, consumer must wait if buffer is empty, whereas
producer must wait if buffer is full.
➢ The buffer can be implemented using any IPC facility.
Algorithm:
1. Create a shared memory segment BUFSIZE of size 1 and attach it.
2. Obtain semaphore id for variables empty, mutex and full using semget
function.
3. Create semaphore for empty, mutex and full as follows:
a. Declare semun, a union of specific commands.
b. The initial values are: 1 for mutex, N for empty and 0 for full.
c. Use semctl function with SETVAL command.
4. Create a child process using fork system call.
a. Make the parent process to be the producer.
b. Make the child process to the consumer.
5. The producer produces 5 items as follows:
a. Call wait operation on semaphores empty and mutex using semop function.
b. Gain access to buffer and produce data for consumption.
c. Call signal operation on semaphores mutex and full using semop function.
6. The consumer consumes 5 items as follows:
a. Call wait operation on semaphores full and mutex using semop function.
b. Gain access to buffer and consume the available data.
c. Call signal operation on semaphores mutex and empty using semop function.
7. Remove shared memory from the system using shmctl with IPC_RMID
argument.
8. Stop.
Program:
/* Producer-Consumer problem using semaphore – pcsem.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define N 5
#define BUFSIZE 1
#define PERMS 0666
int *buffer;
int nextp = 0, nextc = 0;
int mutex, full, empty;
void producer()
{
int data;
if(nextp == N)
nextp = 0;
printf("Enter data for producer to produce : ");
scanf("%d",(buffer + nextp));
nextp++;
}
void consumer()
{
int g;
if(nextc == N)
nextc = 0;
g = *(buffer + nextc++);
printf("\nConsumer consumes data %d", g);
}
void sem_op(int id, int value)
{ struct sembuf op;
int v;
op.sem_num = 0;
op.sem_op = value;
op.sem_flg = SEM_UNDO;
if((v = semop(id, &op, 1)) < 0)
printf("\nError executing semop instruction");
}
void sem_create(int semid, int initval)
{
int semval;
union semun
{
int val;
struct semid_ds *buf;
} s; unsigned short *array;
s.val = initval;
if((semval = semctl(semid, 0, SETVAL, s)) < 0)
printf("\nError in executing semctl");
}
void sem_wait(int id)
{
int value = -1;
sem_op(id, value);
}
void sem_signal(int id)
{
int value = 1;
sem_op(id, value);
}
main()
{
int shmid, i;
pid_t pid;
if((shmid = shmget(1000, BUFSIZE, IPC_CREAT|PERMS)) < 0)
{
printf("\nUnable to create shared memory");
return;
}
if((buffer = (int*)shmat(shmid, (char*)0, 0)) == (int*)-1)
{
printf("\nShared memory allocation error\n");
exit(1);
}
if((mutex = semget(IPC_PRIVATE, 1, PERMS|IPC_CREAT)) == -1)
{
printf("\nCan't create mutex semaphore");
exit(1);
}
if((empty = semget(IPC_PRIVATE, 1, PERMS|IPC_CREAT)) == -1)
{
printf("\nCan't create empty semaphore");
exit(1);
}
if((full = semget(IPC_PRIVATE, 1, PERMS|IPC_CREAT)) ==-1)
{
printf("\nCan't create full semaphore");
exit(1);
}
sem_create(mutex,1);
sem_create(empty,N);
sem_create(full, 0);
if((pid = fork()) < 0)
{ printf("\nError in process creation");
exit(1);
}
else if(pid > 0)
{ for(i=0; i<N; i++)
{ sem_wait(empty); sem_wait(mutex);
producer();
sem_signal(mutex);
sem_signal(full);
}
}
else if(pid == 0)
{ for(i=0; i<N; i++)
{ sem_wait(full); sem_wait(mutex);
consumer();
sem_signal(mutex);
sem_signal(empty);
}
printf("\n");
}
}
Output:
$ cc pcsem.c
$ ./a.out
Enter data for producer to produce : 5
Enter data for producer to produce : 8
Consumer consumes data 5
Enter data for producer to produce : 4
Consumer consumes data 8
Enter data for producer to produce : 2
Consumer consumes data 4
Enter data for producer to produce : 9
Consumer consumes data 2
Consumer consumes data 9
Result:
Thus synchronization between producer and consumer process using
semaphore technique was implemented and executed successfully.
Ex. No: 6 Semaphore Implementation
Date:
Aim:
To demonstrate the utility of semaphore in synchronization and multithreading.
Semaphore:
➢ The POSIX system in Linux has its own built-in semaphore library.
➢ To use it, include semaphore.h.
➢ Compile the code by linking with -lpthread -lrt.
➢ To lock a semaphore or wait, use the sem_wait function.
➢ To release or signal a semaphore, use the sem_post function.
➢ A semaphore is initialised by using sem_init(for processes or threads)
➢ To declare a semaphore, the data type is sem_t.
Algorithm:
1. 2 threads are being created, one 2 seconds after the first one.
2. But the first thread will sleep for 4 seconds after acquiring the lock.
3. Thus the second thread will not enter immediately after it is called, it will
enter 4 – 2 = 2 secs after it is called.
4. Stop.
Result:
Thus semaphore implementation has been demonstrated using c program
successfully.
Ex. No: 7 DEAD LOCK AVOIDANCE USING BANKERS ALGORITHM
Date:
Aim:
To implement deadlock avoidance by using Banker’s Algorithm.
Algorithm:
1. Start the program.
2. Get the values of resources and processes.
3. Get the avail value.
4. After allocation find the need value.
5. Check whether its possible to allocate.
6. If it is possible then the system is in safe state.
7. Else system is not in safety state.
8. If the new request comes then check that the system is in safety or not if we
allow the request.
9. Stop.
Program:
#include<stdio.h>
#include<stdio.h>
main()
{
int r[1][10], av[1][10];
int all[10][10], max[10][10], ne[10][10], w[10],safe[10];
int i=0, j=0, k=0, l=0, np=0, nr=0, count=0, cnt=0;
clrscr();
printf("Enter the number of processes in a system");
scanf("%d", &np);
printf("Enter the number of resources in a system");
scanf("%d",&nr);
for(i=1; i<=nr; i++)
{ printf("Enter no. of instances of resource R%d " ,i);
scanf("%d", &r[0][i]);
av[0][i] = r[0][i];
}
for(i=1; i<=np; i++)
for(j=1; j<=nr; j++)
all[i][j] = ne[i][j] = max[i][j] = w[i]=0;
printf("Enter the allocation matrix");
for(i=1; i<=np; i++)
{ for(j=1; j<=nr; j++)
{ scanf("%d", &all[i][j]);
av[0][j] = av[0][j] - all[i][j];
}
}
printf("Enter the maximum matrix");
for(i=1; i<=np; i++)
{ for(j=1; j<=nr; j++)
{
scanf("%d",&max[i][j]);
}
}
for(i=1; i<=np; i++)
{ for(j=1; j<=nr; j++)
{ ne[i][j] = max[i][j] - all[i][j];
}
}
for(i=1; i<=np; i++)
{ printf("process P%d", i);
for(j=1; j<=nr; j++)
{
printf("\n allocated %d\t",all[i][j]);
printf("maximum %d\t",max[i][j]);
printf("need %d\t",ne[i][j]);
}
printf("\n \n");
}
printf("\nAvailability ");
for(i=1; i<=nr; i++)
printf("R%d %d\t", i, av[0][i]);
printf("\n ");
printf("\n safe sequence");
for(count=1; count<=np; count++)
{ for(i=1; i<=np; i++)
{ cnt = 0;
for(j=1; j<=nr; j++)
{
if(ne[i][j] <= av[0][j] && w[i]==0)
cnt++;
}
if(cnt == nr)
{
k++;
safe[k] = i;
for(l=1; l<=nr; l++)
av[0][l] = av[0][l] + all[i][l];
printf("\n P%d ",safe[k]);
printf("\t Availability ");
for(l=1; l<=nr; l++)
printf("R%d %d\t", l, av[0][l]);
w[i]=1;
}
}
}
getch();
}
Output:
$ cc deadlock.c
$ ./a.out
Enter the number of processes in a system 3
Enter the number of resources in a system 3
Enter no. of instances of resource R1 10
Enter no. of instances of resource R2 7
Enter no. of instances of resource R3 7
process P1
allocated 3 maximum 4 need 1
allocated 2 maximum 4 need 2
allocated 1 maximum 4 need 3
process P2
allocated 1 maximum 3 need 2
allocated 1 maximum 4 need 3
allocated 2 maximum 5 need 3
process P3
allocated 4 maximum 5 need 1
allocated 1 maximum 2 need 1
allocated 2 maximum 4 need 2
Availability R1 2 R2 3 R3 2
safe sequence
P3 Availability R1 6 R2 4 R3 4
P1 Availability R1 9 R2 6 R3 5
P2 Availability R1 10 R2 7 R3 7
Result:
Thus banker’s algorithm for dead lock avoidance was executed successfully.
Ex. No: 8 DEAD LOCK DETECTION
Date:
Aim:
To check whether the process and their request for resources are in a
deadlocked state or safe state.
Algorithm:
1. Mark each process that has a row in the Allocation matrix of all zeros.
2. Initialize a temporary vector W to equal the Available vector.
3. Find an index i such that process i is currently unmarked and the ith row of Q
is less than or equal to W . That is, Qik … Wk, for 1 … k … m. If no such row is
found, terminate the algorithm.
4. If such a row is found, mark process i and add the corresponding row of the
allocation matrix to W. That is, set Wk = Wk + Aik, for 1 … k … m. Return to
step 3.
Program:
#include<stdio.h>
#include<conio.h>
int max[100][100];
int alloc[100][100];
int need[100][100];
int avail[100];
int n, r;
void input();
void show();
void cal();
main()
{
int i,j;
printf("Deadlock Detection Algorithm\n");
input();
show();
cal();
getch();
}
void input()
{
int i,j;
printf("Enter the no of Processes\t");
scanf("%d",&n);
printf("Enter the no of resource instances\t");
scanf("%d", &r);
printf("Enter the Max Matrix\n");
for(i=0; i<n; i++)
for(j=0; j<r; j++)
scanf("%d", &max[i][j]);
printf("Enter the Allocation Matrix\n");
for(i=0; i<n; i++)
for(j=0; j<r; j++)
scanf("%d", &alloc[i][j]);
printf("Enter the available Resources\n");
for(j=0;j<r;j++)
scanf("%d",&avail[j]);
}
void show()
{
int i, j;
printf("Process\t Allocation\t Max\t Available\t");
for(i=0; i<n; i++)
{
printf("\nP%d\t", i+1);
for(j=0; j<r; j++)
{
printf("%d ", alloc[i][j]);
}
printf("\t");
for(j=0; j<r; j++)
{
printf("%d ", max[i][j]);
}
printf("\t");
if(i == 0)
{
for(j=0; j<r; j++)
printf("%d ", avail[j]);
}
}
}
void cal()
{
int finish[100], temp, need[100][100], flag=1, k, c1=0;
int dead[100];
int safe[100];
int i, j;
for(i=0; i<n; i++)
{
finish[i] = 0;
}
/*find need matrix */
for(i=0; i<n; i++)
{
for(j=0; j<r; j++)
{
need[i][j]= max[i][j] - alloc[i][j];
}
}
while(flag)
{ flag=0;
for(i=0;i<n;i++)
{
int c=0;
for(j=0;j<r;j++)
{
if((finish[i]==0) && (need[i][j] <= avail[j]))
{
c++;
if(c == r)
{
for(k=0; k<r; k++)
{
avail[k] += alloc[i][j];
finish[i]=1;
flag=1;
}
if(finish[i] == 1)
{
i=n;
}
j = 0; }}}}}
flag = 0;
for(i=0; i<n; i++)
{
if(finish[i] == 0)
{
dead[j] = i;
j++;
flag = 1;
}
}
if(flag == 1)
{
printf("\n\n System is in Deadlock and the Deadlock process are\n");
for(i=0;i<n;i++)
{
printf("P%d\t", dead[i]);
}
}
else
{
printf("\n No Deadlock Occurs");
}
}
Output:
********** Deadlock Detection Algorithm ************
Enter the no of Processes 3
Enter the no of resource instances 3
Enter the Max Matrix
360
433
344
Enter the Allocation Matrix
333
203
124
Enter the available Resources
120
Process Allocation Max Available
P1 333 360 120
P2 203 433
P3 124 344
Result:
Thus using given state of information deadlocked processe s w e r e
determinedsuccessfully.
Ex. No: 9 THREADING
Date:
Aim:
To demonstrate the concept of threading and synchronization using mutual
exclusion (mutex).
Description:
• Thread synchronization is defined as a mechanism which ensures that two or
more concurrent processes or threads do not simultaneously execute some
particular program segment known as critical section.
• Processes access to critical section is controlled by using synchronization
techniques.
• When one thread starts executing the critical section (serialized segment of
the program) the other thread should wait until the first thread finishes.
• If proper synchronization techniques are not applied, it may cause a race
condition where the values of variables may be unpredictable.
• A Mutex is a lock that we set before using a shared resource and release
after using it.
• When the lock is set, no other thread can access the locked region of code. So
this ensures a synchronized access of shared resources in the code.
Algorithm:
1. Create two threads.
2. Let the threads share a common resource, say counter.
3. Even if thread2 si scheduled to start while thread was not done, access to
shared resource is not done as it is locked by mutex.
4. Once thread1 completes, thread2 starts execution.
5. Stop.
Program:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
pthread_t tid[2];
int counter;
pthread_mutex_t lock;
void* trythis(void *arg)
{
pthread_mutex_lock(&lock);
unsigned long i = 0;
counter += 1;
printf("\n Job %d has started\n", counter);
for(i=0; i<(0xFFFFFFFF);i++)
printf("\n Job %d has finished\n", counter);
pthread_mutex_unlock(&lock);
return NULL;
}
main()
{
int i = 0;
int error;
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init has failed\n");
return 1;
}
while(i < 2)
{
err = pthread_create(&(tid[i]), NULL, &trythis, NULL);
if (error != 0)
printf("\nThread can't be created :[%s]", strerror(error));
i++;
}
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_mutex_destroy(&lock);
return 0;
}
Output:
$ cc filename.c -lpthread
$ ./a.out
Job 1 started
Job 1 finished
Job 2 started
Job 2 finished
Result:
Thus c program for implementing thread synchronization using mutex lock
was executed successfully.
Ex. No: 10 Paging Technique
Date:
Aim:
To implement the concept of paging i.e physical address of a given page to
be determined using page table.
Algorithm:
1. Get process size.
2. Compute number of pages available and display it.
3. Get relative address.
4. Determine the corresponding page.
5. Display page table.
6. Display the physical address.
Program:
#include <stdio.h>
#include <math.h>
main()
{
int size, m, n, pgno, pagetable[3]={5,6,7}, i, j, frameno;
double m1;
int ra=0, ofs;
printf("Enter process size (in KB of max 12KB):");
scanf("%d", &size);
m1 = size / 4;
n = ceil(m1);
printf("Total No. of pages: %d", n);
printf("\nEnter relative address (in hexa) \n");
scanf("%d", &ra);
pgno = ra / 1000;
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("\nPhysical address: %d%d", frameno, ofs);
}
Output:
$ cc paging.c
$ ./a.out
Enter process size (in KB of max 12KB):12
Total No. of pages: 3
Enter relative address (in hexa): 2643
page no=2
page table
0 [5]
1 [6]
2 [7]
Physical address: 7643
Result:
Thus physical address for the given logical address is determined using paging
technique.
Ex. No: 11a Memory Allocation using First Fit
Date:
Aim:
To allocate memory requirements for processes using first fit allocation strategy.
Memory Management:
➢ The first-fit, best-fit, or worst-fit strategy is used to select a free hole from the
set of available holes.
First fit:
➢ Allocate the first hole that is big enough.
➢ Searching starts from the beginning of set of holes.
Algorithm:
1. Declare structures hole and process to hold information about set of holes
and processes respectively.
2. Get number of holes, say nh.
3. Get the size of each hole.
4. Get number of processes, say np.
5. Get the memory requirements for each process.
6. Allocate processes to holes, by examining each hole as follows:
a. If hole size > process size then,
i. Mark process as allocated to that hole.
ii. Decrement hole size by process size.
b. Otherwise check the next from the set of hole.
7. Print the list of process and their allocated holes or unallocated status.
8. Print the list of holes, their actual and current availability.
9. Stop.
Program:
/* First fit allocation - ffit.c */
#include <stdio.h>
struct process
{ int size;
int flag;
int holeid;
} p[10];
struct hole
{ int size;
int actual;
} h[10];
main()
{
int i, np, nh, j;
printf("Enter the number of Holes : ");
scanf("%d", &nh);
for(i=0; i<nh; i++)
{
printf("Enter size for hole H%d : ",i);
scanf("%d", &h[i].size);
h[i].actual =h[i].size;
}
printf("\n Enter number of process : " );
scanf("%d",&np);
for(i=0;i<np;i++)
{
printf("Enter the size of process P%d : ",i);
scanf("%d", &p[i].size);
p[i].flag = 0;
}
for(i=0; i<np; i++)
{
for(j=0; j<nh; j++)
{
if(p[i].flag != 1)
{
if(p[i].size <= h[j].size)
{
p[i].flag = 1; p[i].holeid = j;
h[j].size -= p[i].size;
}
}
}}
printf("\n\tFirst fit\n");
printf("\nProcess\tPSize\tHole");
for(i=0; i<np; i++)
{
if(p[i].flag != 1)
printf("\nP%d\t%d\tNot allocated", i, p[i].size);
else
printf("\nP%d\t%d\tH%d", i, p[i].size, p[i].holeid);
}
printf("\n\nHole\tActual\tAvailable");
for(i=0; i<nh ;i++)
printf("\nH%d\t%d\t%d", i, h[i].actual, h[i].size);
printf("\n");
}
Output:
$ cc ffit.c
$ ./a.out
Enter the number of Holes : 5
Enter size for hole H0 : 100
Enter size for hole H1 : 500
Enter size for hole H2 : 200
Enter size for hole H3 : 300
Enter size for hole H4 : 600
First fit
Result:
Thus memory allocation using first fit method was implemented and executed
successfully.
Ex. No: 11b Memory Allocation using Best Fit
Date:
Aim:
To allocate memory requirements for processes using best fit allocation.
Best fit:
➢ Allocate the smallest hole that is big enough.
➢ The list of free holes is kept sorted according to size in ascending order.
➢ This strategy produces smallest leftover holes.
Algorithm:
1. Declare structures hole and process to hold information about set of holes.
and processes respectively.
2. Get number of holes, say nh.
3. Get the size of each hole.
4. Get number of processes, say np.
5. Get the memory requirements for each process.
6. Allocate processes to holes, by examining each hole as follows:
a. Sort the holes according to their sizes in ascending order.
b. If hole size > process size then,
i. Mark process as allocated to that hole.
ii. Decrement hole size by process size.
c. Otherwise check the next from the set of sorted hole.
7. Print the list of process and their allocated holes or unallocated status.
8. Print the list of holes, their actual and current availability.
9. Stop.
Program:
#include <stdio.h>
struct process
{
int size; int
flag; int
holeid;
} p[10];
struct hole
{
int hid;
int size;
int actual;
} h[10];
main()
{
int i, np, nh, j;
void bsort(struct hole[], int);
printf("Enter the number of Holes : ");
scanf("%d", &nh);
for(i=0; i<nh; i++)
{
printf("Enter size for hole H%d : ",i);
scanf("%d", &h[i].size);
h[i].actual =h[i].size;
h[i].hid = i;
}
printf("\nEnter number of process : " );
scanf("%d",&np);
for(i=0;i<np;i++)
{
printf("enter the size of process P%d : ",i);
scanf("%d", &p[i].size);
p[i].flag = 0;
}
for(i=0; i<np; i++)
{
bsort(h, nh);
for(j=0; j<nh; j++)
{
if(p[i].flag != 1)
{
if(p[i].size <= h[j].size)
{
p[i].flag = 1;
p[i].holeid =h[j].hid;
} h[j].size -= p[i].size;
}}}
printf("\n\tBest fit\n");
printf("\nProcess\tPSize\tHole");
for(i=0; i<np; i++)
{
if(p[i].flag != 1)
printf("\nP%d\t%d\tNot allocated", i, p[i].size);
else
printf("\nP%d\t%d\tH%d", i, p[i].size, p[i].holeid);
}
printf("\n\nHole\tActual\tAvailable"); for(i=0; i<nh ;i++)
printf("\nH%d\t%d\t%d", h[i].hid, h[i].actual, h[i].size);
printf("\n");
}
void bsort(struct hole bh[], int n)
{ struct hole temp;
int i,j;
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if(bh[i].size > bh[j].size)
{
temp = bh[i];
bh[i] = bh[j];
bh[j] = temp;
}}}}
Output:
$ cc bfit.c
$ ./a.out
Enter the number of Holes: 5
Enter size for hole H0 : 100
Enter size for hole H1 : 500
Enter size for hole H2 : 200
Enter size for hole H3 : 300
Enter size for hole H4 : 600
Result:
Thus memory allocation using best fit method was implemented and executed
successfully.
Ex. No: 12a Page Replacement - FIFO (First In First Out)
Date:
Aim:
To implement the concept of demand paging for a reference string using FIFO
method.
FIFO:
➢ Page replacement is based on when the page was brought into memory.
➢ When a page should be replaced, the oldest one is chosen.
➢ Generally, implemented using a FIFO queue.
➢ Simple to implement, but not efficient.
➢ Results in more page faults.
➢ The page-fault may increase, even if frame size is increased (Belady's
anomaly)
Algorithm:
1. Get length of the reference string, say l.
2. Get reference string and store it in an array, say rs.
3. Get number of frames, say nf.
4. Initalize frame array upto length nf to -1.
5. Initialize position of the oldest page, say j to 0.
6. Initialize no. of page faults, say count to 0.
7. For each page in reference string in the given order, examine:
a. Check whether page exist in the frame array.
b. If it does not exist then,
i. Replace page in position j.
ii. Compute page replacement position as (j+1) modulus nf.
iii. Increment count by 1.
iv. Display pages in frame array.
8. Print count.
9. Stop.
Program:
#include <stdio.h>
main()
{
int i, j, l, rs[50], frame[10], nf, k, avail, count=0;
printf("Enter length of reference string : ");
scanf("%d", &l);
printf("Enter reference string :\n");
for(i=1; i<=l; i++)
scanf("%d", &rs[i]);
printf("Enter number of frames : ");
scanf("%d", &nf);
for(i=0; i<nf; i++)
frame[i] = -1;
j = 0;
printf("\n Ref. str Page frames");
for(i=1; i<=l; i++)
{ printf("\n%4d\t", rs[i]);
avail = 0;
for(k=0; k<nf; k++)
if(frame[k] == rs[i])
avail = 1;
if(avail == 0)
{ frame[j] = rs[i];
j = (j+1) % nf;
count++;
for(k=0; k<nf; k++)
printf("%4d",frame[k]);
}}
printf("\n\nTotal no. of page faults : %d\n",count);
}
Output:
$ cc fifo.c
$ ./a.out
Enter length of reference string: 20
Enter reference string:
123421562123763
Enter number of frames: 5
Ref Page frames
.
str
1 1 -1 -1 -1 -1
2 1 2 -1 -1 -1
3 1 2 3 -1 -1
4 1 2 3 4 -1
2
1
5 1 2 3 4 5
6 6 2 3 4 5
2
1 6 1 3 4 5
2 6 1 2 4 5
3 6 1 2 3 5
7 6 1 2 3 7
6
3
Total no. of page faults: 10
Result:
Thus page replacement using FIFO algorithm was implemented and executed
successfully.
Ex. No: 12b Page Replacement - LRU (Least Recently Used)
Date:
Aim:
To implement the concept of demand paging for a reference string using LRU
method.
LRU:
➢ Pages used in the recent past are used as an approximation of future usage.
➢ The page that has not been used for a longer period of time is replaced.
➢ LRU is efficient but not optimal.
➢ Implementation of LRU requires hardware support, such as counters/stack.
Algorithm:
1. Get length of the reference string, say len.
2. Get reference string and store it in an array, say rs.
3. Get number of frames, say nf.
4. Create access array to store counter that indicates a measure of recent usage.
5. Create a function arrmin that returns position of minimum of the given
array.
6. Initalize frame array upto length nf to -1.
7. Initialize position of the page replacement, say j to 0.
8. Initialize freq to 0 to track page frequency.
9. Initialize no. of page faults, say count to 0.
10. For each page in reference string in the given order, examine:
a. Check whether page exist in the frame array.
b. If page exist in memory then,
i. Store incremented freq for that page position in access array.
c. If page does not exist in memory then,
i. Check for any empty frames.
ii. If there is an empty frame,
➢ Assign that frame to the page.
➢ Store incremented freq for that page position in access
array.
➢ Increment count.
iii. If there is no free frame then,
➢ Determine page to be replaced using arrmin function.
➢ Store incremented freq for that page position in access
array.
➢ Increment count.
iv. Display pages in frame array.
11. Print count.
12. Stop.
Program:
/* LRU page replacement - lrupr.c */
#include <stdio.h>
int arrmin(int[], int);
main()
{
int i,j,len,rs[50],frame[10],nf,k,avail,count=0;
int access[10], freq=0, dm;
printf("Length of Reference string : ");
scanf("%d", &len);
printf("Enter reference string :\n");
for(i=1; i<=len; i++)
scanf("%d", &rs[i]);
printf("Enter no. of frames : ");
scanf("%d", &nf);
for(i=0; i<nf; i++)
frame[i] = -1;
j = 0;
printf("\nRef. Str Page frames");
for(i=1; i<=len; i++)
{
printf("\n%4d\t", rs[i]);
avail = 0;
for(k=0; k<nf; k++)
{
if(frame[k] == rs[i])
{
avail = 1;
access[k] = ++freq;
break;
}}
if(avail == 0)
{ dm = 0;
for(k=0; k<nf; k++)
{ if(frame[k] == -1)
dm = 1;
break;
}
if(dm == 1)
{ frame[k] = rs[i];
access[k] = ++freq;
count++;
}
else
{ j = arrmin(access, nf);
frame[j] = rs[i];
access[j] = ++freq;
count++;
}
for(k=0; k<nf; k++)
printf("%4d", frame[k]);
}}
printf("\n\nTotal no. of page faults : %d\n", count);
}
int arrmin(int a[], int n)
{
int i, min = a[0];
for(i=1; i<n; i++)
if (min > a[i])
min = a[i];
for(i=0; i<n; i++)
if (min == a[i])
return i;
}
Output:
$ cc lrupr.c
$ ./a.out
Length of Reference string: 15
Enter reference string:
123421562123763
Enter no. of frames: 5
Result:
Thus page replacement using LRU algorithm was implemented and executed
successfully.
Ex. No: 13a File Organization - Single-Level Directory
Date:
Aim:
To organize files in a single level directory structure, i.e. without sub-
directories.
Algorithm:
1. Get name of directory for the user to store all the files.
2. Display menu.
3. Accept choice.
4. If choice =1 then,
Accept filename. Without any collision, store it in the directory.
5. If choice =2 then,
Accept filename. Remove filename from the directory array.
6. If choice =3 then,
Accept filename. Check for existence of file in the directory array.
7. If choice =4 then,
List all files in the directory array.
8. If choice=5 then Stop.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct
{
char dname[10];
char fname[25][10];
int fcnt;
}dir;
main()
{
int i, ch;
char f[30];
dir.fcnt = 0;
printf("\nEnter name of directory -- ");
scanf("%s", dir.dname);
while(1)
{ printf("\n 1. Create File\t2. Delete File\t3. Search File \n4. Display Files\t5. Exit\n
Enter your choice--");
scanf("%d",&ch);
switch(ch)
{ case 1:
printf("\n Enter the name of the file -- ");
scanf("%s", dir.fname[dir.fcnt]);
dir.fcnt++;
break;
case 2:
printf("\n Enter the name of the file -- ");
scanf("%s", f);
for(i=0; i<dir.fcnt; i++)
{
if(strcmp(f, dir.fname[i]) == 0)
{
printf("File %s is deleted ",f);
strcpy(dir.fname[i], dir.fname[dir.fcnt-1]);
break;
}
}
if(i == dir.fcnt)
printf("File %s not found", f);
else
dir.fcnt--; break;
case 3:
printf("\n Enter the name of the file -- ");
scanf("%s", f);
for(i=0; i<dir.fcnt; i++)
{
if(strcmp(f, dir.fname[i]) == 0)
{
printf("File %s is found ", f);
break;
}}
if(i == dir.fcnt)
printf("File %s not found", f);
break;
case 4:
if(dir.fcnt == 0)
printf("\n Directory Empty");
else
{
printf("\n The Files are -- ");
for(i=0; i<dir.fcnt; i++)
printf("\t%s", dir.fname[i]);
}
break;
default:
exit(0);
}
}
getch();
}
Output:
$ cc sld.c
$ ./a.out
Enter name of directory -- CSE
1. Create File 2. Delete File 3. Search File
4. Display Files 5. Exit
Enter your choice -- 1
Enter the name of the file -- fcfs
Result:
Thus files organization based on single level directory structure technique was
implemented and executed successfully.
Ex. No: 13 File Organization - Two-level directory
Date:
Aim:
To organize files as two-level directory with each user having his own user file
directory (UFD).
Algorithm:
1. Display menu.
2. Accept choice.
3. If choice =1 then,
Accept directory name. Create an entry for that directory.
4. If choice =2 then,
Get directory name. If directory exist, then accept filename without
collision else report error.
5. If choice =3 then,
Get directory name. If directory exist, then Get filename. If file exist in
that directory, then delete entry else report error.
6. If choice =4 then,
Get directory name. If directory exist, then Get filename. If file exist in
that directory, then display filename else report error.
7. If choice =5, then display files directory-wise.
8. If choice =6, then Stop.
Program:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct
{ char dname[10], fname[10][10];
int fcnt;
}dir[10];
main()
{
int i, ch, dcnt, k;
char f[30], d[30];
clrscr();
dcnt=0;
while(1)
{
printf("\n\n 1. Create Directory\t 2. Create File\t 3.Delete File");
printf("\n 4. Search File \t \t 5. Display \t 6. Exit \n Enter your choice -- ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("\n Enter name of directory -- ");
scanf("%s", dir[dcnt].dname);
dir[dcnt].fcnt = 0;
dcnt++;
printf("Directory created");
break;
case 2:
printf("\n Enter name of the directory -- ");
scanf("%s", d);
for(i=0; i<dcnt; i++)
if(strcmp(d,dir[i].dname) == 0)
{
printf("Enter name of the file -- ");
scanf("%s", dir[i].fname[dir[i].fcnt]);
dir[i].fcnt++;
printf("File created");
break;
}
if(i == dcnt)
printf("Directory %s not found",d);
break;
case 3:
printf("\nEnter name of the directory -- ");
scanf("%s", d);
for(i=0; i<dcnt; i++)
{
if(strcmp(d,dir[i].dname) == 0)
{
printf("Enter name of the file -- ");
scanf("%s", f);
for(k=0; k<dir[i].fcnt; k++)
{
if(strcmp(f, dir[i].fname[k]) == 0)
{
printf("File %s is deleted ", f);
dir[i].fcnt--;
strcpy(dir[i].fname[k], dir[i].fname[dir[i].fcnt]);
goto jmp;
}
}
printf("File %s not found",f);
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)
{
printf("Enter the name of the file -- ");
scanf("%s", f);
for(k=0; k<dir[i].fcnt; k++)
{
if(strcmp(f, dir[i].fname[k]) == 0)
{
printf("File %s is found ", f);
goto jmp1;
}}
printf("File %s not found", f);
goto jmp1;
}}
printf("Directory %s not found", d); jmp1: break;
case 5:
if(dcnt == 0)
printf("\nNo Directory's ");
else
{
printf("\nDirectory\tFiles");
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);
}
}
getch();
}
Output:
$ cc tld.c
$ ./a.out
1. Create Directory 2. Create File 3. Delete File
4. Search File 5. Display 6. Exit
Enter your choice -- 1
Enter name of directory – CSE
Directory created
Result:
Thus user files have been stored in their respective directories and retrieved
easily using two level directory structure of file organization.
Ex. No: 14a Contiguous Allocation
Date:
Aim:
To implement file allocation on free disk space in a contiguous manner.
File Allocation:
The three methods of allocating disk space are:
1. Contiguous allocation
2. Linked allocation
3. Indexed allocation
Contiguous Allocation:
➢ Each file occupies a set of contiguous block on the disk.
➢ The number of disk seeks required is minimal.
➢ The directory contains address of starting block and number of contiguous
block (length) occupied.
➢ Supports both sequential and direct access.
➢ First / best fit is commonly used for selecting a hole.
Algorithm:
1. Assume no. of blocks in the disk as 20 and all are free.
2. Display the status of disk blocks before allocation.
3. For each file to be allocated:
a. Get the filename, start address and file length
b. If start + length > 20, then goto step 2.
c. Check to see whether any block in the range (start, start + length-1)
is allocated. If so, then go to step 2.
d. Allocate blocks to the file contiguously from start block to start +
length – 1.
4. Display directory entries.
5. Display status of disk blocks after allocation.
6. Stop.
Program:
/* Contiguous Allocation - cntalloc.c */
#include <stdio.h>
#include <string.h>
int num=0, length[10], start[10];
char fid[20][4], a[20][4];
void directory()
{
int i;
printf("\n File Start Length\n");
for(i=0; i<num; i++)
printf("%-4s %3d %6d\n",fid[i],start[i],length[i]);
}
void display()
{ int i;
for(i=0; i<20; i++)
printf("%4d",i);
printf("\n");
for(i=0; i<20; i++)
printf("%4s", a[i]);
}
main()
{ int i,n,k,temp,st,nb,ch,flag;
char id[4];
for(i=0; i<20; i++)
strcpy(a[i], "");
printf("Disk space before allocation:\n");
display();
do
{ printf("\nEnter File name (max 3 char) : ");
scanf("%s", id);
printf("Enter start block : ");
scanf("%d", &st);
printf("Enter no. of blocks : ");
scanf("%d", &nb);
strcpy(fid[num], id);
length[num] = nb;
flag = 0;
if((st+nb) > 20)
{ printf("Requirement exceeds range\n");
continue;
}
for(i=st; i<(st+nb); i++)
if(strcmp(a[i], "") != 0)
flag = 1;
if(flag == 1)
{
printf("Contiguous allocation not possible.\n");
continue;
}
start[num] = st;
for(i=st; i<(st+nb);i++)
strcpy(a[i], id);;
printf("Allocation done\n");
num++;
printf("\n Any more allocation (1. yes / 2. no)? : ");
scanf("%d", &ch);
} while (ch == 1);
printf("\n\t\t\t Contiguous Allocation\n");
printf("Directory:");
directory();
printf("\nDisk space after allocation:\n");
display(); }
Output:
$ cc cntalloc.c
$ ./a.out
Disk space before allocation:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Enter File name (max 3 char) : cp
Enter start block : 14
Enter no. of blocks : 3
Allocation done
Any more allocation (1. yes / 2. no)? : 1
Contiguous Allocation
Directory:
File Start Length
cp 14 3
tr 10 3
mv 0 2
Disk space after allocation:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
mv mv tr tr tr cp cp cp
Result:
Thus contiguous allocation is done for files with the available free blocks.
Ex. No: 14b LINKED FILE ALLOCATION
Date:
Aim:
To implement file allocation on free disk space using linked file allocation
strategy.
Linked Allocation:
➢ Each file is a linked list of disk blocks.
➢ The directory contains a pointer to first and last blocks of the file.
➢ The first block contains a pointer to the second one, second to third and so
on.
➢ File size need not be known in advance, as in contiguous allocation.
➢ No external fragmentation.
➢ Supports sequential access only.
Indexed Allocation:
➢ In indexed allocation, all pointers are put in a single block known as index
block.
➢ The directory contains address of the index block.
➢ The ith entry in the index block points to ith block of the file.
➢ Indexed allocation supports direct access.
➢ It suffers from pointer overhead, i.e wastage of space in storing pointers.
Algorithm:
1. Get no. of files.
2. Accept filenames and number of blocks for each file.
3. Obtain start block for each file.
4. Obtain other blocks for each file.
5. Check for block availability before allocation.
6. If block is unavailable, then report error.
7. Accept file name.
8. Display linked file allocation blocks for that file.
9. Stop.
Program:
#include <stdio.h>
#include <conio.h>
#include <string.h>
main()
{
static int b[20], i, j, blocks[20][20];
char F[20][20], S[20], ch;
int sb[20], eb[20], x, n;
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 No. of blocks:",
i+1);scanf("%d",&b[i]);
}
for(i=0;i<n;i++)
{
printf("\n Enter Starting block of file%d::",i+1);
scanf("%d", &sb[i]);
printf("\n Enter blocks for file%d::\n",
i+1);for(j=0; j<b[i]-1;)
{
printf("\n Enter the %dblock ::",
j+2);scanf("%d", &x);
if(b[i] != 0)
{
}
else
}
}
blocks[i][j] = x;
j++;
printf("\n Invalid block::");
printf("\nEnter the Filename
:");scanf("%s", &S);
for(i=0; i<n; i++)
{
if(strcmp(F[i],S) == 0)
{
printf("\nFname\tBsize\tStart\tBlocks\n");
printf("\n\n");printf("\n%s\t%d\t%d\t", F[i], b[i], sb[i]);
printf("%d-
>",sb[i]);for(j=0;
j<b[i]; j++)
{
if(b[i] != 0)
printf("%d->", blocks[i][j]);
}
}
}
printf("\n\n");getch();
}
Output:
$ cc linked.c
$ ./a.out
Result:
Thus blocks for file were allocated using linked allocation method and executed
successfully.
Ex. No: 15a FCFS Disk Scheduling
Date:
Aim:
To implement FCFS disk scheduling algorithms using C program.
Algorithm:
1. Let Request array represents an array storing indexes of tracks that have been requested
in ascending order of their time of arrival. ‘head’ is the position of disk head.
2. Let us one by one take the tracks in default order and calculate the absolute distance of
the track from the head.
3. Increment the total seek count with this distance.
4. Currently serviced track position now becomes the new head position.
5. Go to step 2 until all tracks in request array have not been serviced.
Program:
#include<stdio.h>
main()
{
int t[20], n, I, j, tohm[20], tot=0;
float avhm;
clrscr();
printf(“enter the no.of tracks”);
scanf(“%d”,&n);
printf(“enter the tracks to be traversed”);
for(i=2;i<n+2;i++)
scanf(“%d”,&t*i+);
for(i=1;i<n+1;i++)
{
tohm[i]=t[i+1]-t[i];
if(tohm[i]<0) tohm[i]=tohm[i]*(-1);
}
for(i=1;i<n+1;i++)
tot+=tohm[i];
avhm=(float)tot/n;
printf(“Tracks traversed\tDifference between tracks\n”);
for(i=1;i<n+1;i++)
printf(“%d\t\t\t%d\n”,t*i+,tohm*i+);
printf("\nAverage headermovements:%f",avhm);
getch();
}
Input:
Enter no. of tracks:9
Enter track position: 55 58 60 70 18 90 150 160 184
Output:
Tracks traversed Difference between tracks
55 45
58 3
60 2
70 10
18 52
90 72
150 60
160 10
184 24
Result:
Thus FCFS disk scheduling algorithm is implemented and executed successfully.
Ex. No: 15b SCAN DISK SCHEDULING ALGORITHM
Date:
Aim:
To implement SCAN disk scheduling algorithms using C program.
Algorithm:
1. Start the program.
2. Mark the ‘head’ as the initial position of disk head.
3. Let request array represent an array storing indexes of track that have been requested
in ascending order of their time of arrival.
4. Let direction represents whether the head is moving towards left or right.
5. In the direction in which head is moving service all tracks one by one.
6. Calculate the absolute distance of the track from the head.
7. Increments the total seek count with this distance.
8. Currently serviced track position now becomes the new head position.
9. Go to step 5 until we reach at one of the ends of the disk.
10. If reach at the end of the disk reverse the direction and go to step 4 until all tracks in
request array have not been serviced.
Program:
#include<stdio.h>
main ()
{
int t[20], d[20], h, i, j, n, temp, k, atr[20], tot, p, sum=0; clrscr();
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);
getch();
}
Input:
Enter no.of tracks:9
Enter track position: 55 58 60 70 18 90 150 160 184
Output:
Tracks traversed Difference between tracks
150 50
160 10
184 24
90 94
70 20
60 10
58 2
55 3
18 37
Result:
Thus SCAN disk scheduling algorithm is implemented and executed successfully.
Ex. No: 15b C-SCAN DISK SCHEDULING ALGORITHM
Date:
Aim:
To implement C-SCAN disk scheduling algorithms using C program.
Algorithm:
1. Start the program.
2. Mark the ‘head’ as the initial position of disk head.
3. Let request array represent an array storing indexes of track that have been requested
in ascending order of their time of arrival.
4. The head services only in the right direction from 0 to the size of the disk.
5. While moving in the left directions do not service any of the tracks.
6. When we reach the beginning (left end) reverse the direction.
7. While moving in the right direction it services all tracks one by one.
8. While moving in the right directions calculate the absolute distance of the track from the
head.
9. Increment the total seeks count with this distance.
10. Currently serviced track position now becomes the new head position.
11. Go to step 8 until we reach the right end of the disk.
12. If we reach the right end of the disk reverse the direction and go to step 5 until all
tracks in the request array have not been serviced.
Program:
#include<stdio.h>
main()
{
int t[20], d[20], h, i, j, n, temp, k, atr[20], tot, p, sum=0;
clrscr();
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 total tracks");
scanf("%d",&tot);
t[2]=tot-1;
printf("enter the tracks");
for(i=3;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])
{
for(i=0;i<=n+2;i++) if(t[i]==h);
j=i;
break;
temp=t[j]; t[j]=t[j+1];
t[j+1]=temp
}
p=0;
while(t[j]!=tot-1)
{
atr[p]=t[j]; j++;
p++;
}
atr[p]=t[j]; p++;
i=0;
while(p!=(n+3) && t[i]!=t[h])
{
atr[p]=t[i]; i++; p++;
}
for(j=0;j<n+2;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("total header movements%d",sum);
printf("avg is %f",(float)sum/n);
getch();
}
Input:
Enter the track position : 55 58 60 70 18 90 150 160 184
Enter starting position : 100
Output:
Tracks traversed Difference Between tracks
150 50
160 10
184 24
18 240
55 37
58 3
60 2
70 10
90 20
Average seek time: 35.7777779
Result:
Thus C-SCAN disk scheduling algorithm is implemented and executed successfully.
Ex.No:16 Install any guest operating system like Linux using VMware.
Procedure:
Part 1: Prepare a Computer for Virtualization
Part 2: Create a Virtual Machine
Result:
Thus Installation of operating system like Linux using VMware was done
successfully.