Operating System Lab Manual
Operating System Lab Manual
LAB MANUAL
LIST OF EXPERIMENTS
Ex.No. Experiment Name
1 A. Operating system Installation, B. Basic Linux commands, C.Filter and admin commands
2 Process Creation using fork() and Usage of getpid(), getppid(), wait() functions
3 Multithreading
5 Reader-Writer problem
15 File organization schemes for single level and two level directory
Linux operating system can be installed as either dual OS in your system or you
can install through a virtual machine (VM).
Steps
1. Download VMware Player or Workstation recent version.
6. Select "Installer disc image (ISO)", click "Browse" to select the Ubuntu ISO
file, click "Open" then "Next".
7. You have to type in "Full name", "User name" that must only consist of lowercase
and numbers then you must enter a password. After you finished, click "Next". 8. You
can type in a different name in "Virtual machine name" or leave as is and select an
appropriate location to store the virtual machine by clicking on "Browse" that is next to
"Location" -- you should place it in a drive/partition that has at least 5GB of free space.
After you selected the location click "OK" then "Next".
9. In "Maximum disk size" per Ubuntu recommendations you should allocate at least
5GB -- double is recommended to avoid running out of free space.
10. Select "Store virtual disk as a single file" for optimum performance and click
"Next". 11. Click on "Customize" and go to "Memory" to allocate more RAM -- 1GB
should suffice, but more is always better if you can spare from the installed RAM.
12. Go to "Processors" and select the "Number of processors" that for a normal
computer is 1 and "Number of cores per processor" that is 1 for single core, 2 for
dual core, 4 for quad core and so on -- this is to insure optimum performance of
the virtual machine.
13. Click "Close" then "Finish" to start the Ubuntu install process.
Click on Install
21CSC202J-OPERATING SYSTEMS LAB
Now
Launch the Ubuntu
21CSC202J-OPERATING SYSTEMS LAB
name : Any meaningful
name Password: any name
21CSC202J-OPERATING SYSTEMS LAB
Result:
a) Basics
1. echo SRM �� to display the string SRM
2. clear �� to clear the screen
3. date �� to display the current date and time
4. cal 2003 �� to display the calendar for the year 2003
cal 6 2003 �� to display the calendar for the June-2003
5. passwd �� to change password
6. mv f1 f2 �� rename file f1 as f2
extension ‘c’ 3. ls [gpy]et �� list files whose first letter is any one of the character g, p or y and
e) I/O Redirection
1. Input redirection
wc –l < ex1 �� To find the number of lines of the file ‘ex1’
2. Output redirection
who > f2 �� the output of ‘who’ will be redirected to file f2 3. cat >> f1 �� to append more into the
file f1
f) Piping
Syntax : Command1 | command2
Output of the command1 is transferred to the command2 as input. Finally output of the command2 will
be displayed on the monitor.
head –6 f1 |tail –2 �� prints the 5th & 6th lines of the file f1.
g) Environment variables
1. echo $HOME �� display the path of the home directory
h) File Permission
-- chmod command is used to change the access permission of a file.
Method-1
Syntax : chmod [ugo] [+/-] [ rwxa ] filename
FILTERS
1. cut
▪ Used to cut characters or fileds from a file/input
▪ By default, tab is the filed separator(delimiter). If the fileds of the files are separated by any other
character, we need to specify explicitly by –d option
2. grep
▪ Used to search one or more files for a particular pattern.
3. sort
▪ Used to sort the file in order
4. Uniq
▪ Displays unique lines of a sorted file
Syntax : uniq filename
-d option displays only the duplicate lines
-c displays unique lines with no. of occurrences.
5. diff
▪ Used to differentiate two files
Syntax : diff f1 f2
compare two files f1 & f2 and prints all the lines that are differed between f1 & f2.
Result:
The above commands are successfully executed and verified.
lO M oA R cP S D| 28114020 l
O
Mo
AR
cP
SD
|
2
8
1
1
4
0
2
0
Aim :
To write a program for process Creation using fork() and usage of getpid(), getppid(),
wait() function.
Description:
Algorithm
Step 1 : Open the terminal and edit your program and save with extension
“.c” Ex. nano test.c
Step 2 : Compile your program using gcc compiler
Ex. gcc test.c ➔ Output file will be “a.out”
(or)
gcc –o test text.c ➔ Output file will be “test”
Step 3 : Correct the errors if any and run the program
Ex. ./a.out (or) ./test
Syntax for process creation
int fork();
Returns 0 in child process and child process ID in parent process.
Other Related Functions
int getpid() ➔ returns the current process ID
int getppid() ➔ returns the parent process ID
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(){
fork();
fork();
printf("Hello World\n"); }
21CSC202J-OPERATING SYSTEMS LAB
• Usage of getpid() and getppid()
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void main()
{
/variable to store calling function's
int process_id, p_ process_id;
//getpid() - will return process id of calling function
process_id = getpid();
//getppid() - will return process id of parent function
p_process_id = getppid();
//printing the process ids
printf("The process id: %d\n",process_id);
printf("The process id of parent function: %d\n",p_process_id);
}
21CSC202J-OPERATING SYSTEMS LAB
• Usage of wait()
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
int main()
{
pid_t cpid;
if (fork()== 0)
exit(0); /* terminate child */
else
cpid = wait(NULL); /* reaping parent */
printf("Parent pid = %d\n", getpid());
printf("Child pid = %d\n", cpid);
return 0;
} O M oA R cP S D| 2 81 1 40 20
Output:
Result :
Thus Successfully completed Process Creation using fork() and Usage of getpid(),
getppid(), wait() functions.
cP S D| 2 81 1 40 20
21CSC202J-OPERATING SYSTEMS LAB
Aim :
Description:
Multithreading is the ability of a program or an operating system to enable more than one user at a
time without requiring multiple copies of the program running on the computer. Multithreading
can also handle multiple requests from the same user.
To implement and study Multithreading and pthread in C
Parameters:
· thread: pointer to an unsigned integer value that returns the thread id of the thread
created.
· attr: pointer to a structure that is used to define thread attributes like detached state,
scheduling policy, stack address, etc. Set to NULL for default thread attributes.
· start_routine: pointer to a subroutine that is executed by the thread. The return type and
parameter type of the subroutine must be of type void *. The function has a single attribute but if
multiple values need to be passed to the function, a struct must be used.
· arg: pointer to void that contains the arguments to the function defined in the earlier
argument
b. pthread_exit: used to terminate a thread
Syntax:
void pthread_exit(void *retval);
Parameters: This method accepts a mandatory parameter retval which is the pointer to an integer
that stores the return status of the thread terminated. The scope of this variable must be global so
that any thread waiting to join this thread may read the return status.
Syntax:
int pthread_join(pthread_t th,void **thread_return);
· th: thread id of the thread for which the current thread waits.
· thread_return: pointer to the location where the exit status of the thread
mentioned in th is stored.
d. pthread_self: used to get the thread id of the current thread.
Syntax:
pthread_t pthread_self(void);
e. pthread_equal: compares whether two threads are the same or not. If the two threads
are equal, the function returns a non-zero value otherwise zero.
Syntax:
int pthread_equal(pthread_t t1,
pthread_t t2);
Program :
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX 1000
#define MAX_THREAD 4
int array[1000];
int sum[4] = { 0 };
int arraypart = 0;
for (int i = thread_part * (MAX / 4); i < (thread_part + 1) * (MAX / 4); i++)
{
sum[thread_part] += array[i];
}
}
void testSum()
{
pthread_t threads[MAX_THREAD];
// joining threads
for (int i = 0; i < MAX_THREAD; i++)
{
pthread_join(threads[i], NULL);
}
}
void readfile(char* file_name)
{
char ch;
FILE *fp;
fp = fopen(file_name,"r"); // read mode
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
21CSC202J-OPERATING SYSTEMS LAB
int i=0;
i++;
} fclose(fp);
lO M oA R cP S D| 2 81 1 40 20
array.\n\n"); }
Aim :
To implement Mutual Exclusion using semaphore and monitor
Description:
Semaphore
Semaphore is used to implement process synchronization. This is to protect critical region
shared among multiples processes.
key ➔ semaphore id
struct sembuf {
};
21CSC202J-OPERATING SYSTEMS LAB
Algorithm:
Step2: initialize the semaphore structures and write a Function to initialise the semaphore variables,
condition and mutual exclusion
Step3:write an program coding for initialize the fork and locks the mutex using pthread mutex loc() for
access critical section.
Step4: write the statement for wakes up one waiting thread and finding the value for debugging then print
it.
Step5:write the statement for philospher thread creation and display the result.
Program :
USING SEMAPHORE
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include<errno.h>
#include <stdlib.h>
#include<sched.h>
int philNo[5] = { 0, 1, 2, 3, 4 };
// my_semaphore structure
typedef struct {
return 0;
}
//This locks the mutex so that only thread can access the critical section at a time
pthread_mutex_lock(&sema->mutex);
sema->cnt = sema->cnt + 1;
pthread_cond_signal(&sema->conditional_variable);
lO M oA R cP S D| 2 81 1 40 20
// A woken thread must acquire the lock, so it will also have to wait until we call unlock
pthread_mutex_unlock(&sema->mutex);
return 0;
}
int wait(my_semaphore *sema) {
//This locks the mutex so that only thread can access the critical section at a time
pthread_mutex_lock(&sema->mutex);
// While the semaphore count variable value is 0 the mutex is blocked on the conditon
variable
while (!(sema->cnt))
pthread_cond_wait(&sema->conditional_variable, &sema-
>mutex); // unlock mutex, wait, relock mutex
sema->cnt = sema->cnt - 1;
return 0;
}
// Print semaphore value for debugging
void signal1(my_semaphore *sema) {
printf("Semaphore variable value = %d\n", sema->cnt);
}
// Declaring the semaphore variables which are the shared resources by the threads
my_semaphore forks[5], bowls;
wait(&bowls);
// This puts a wait condition on the forks to be used by the current philospher so
21CSC202J-OPERATING SYSTEMS LAB
that the philospher can access these forks whenever they are free
wait(&forks[*i]);
wait(&forks[(*i+4)%5]);
sleep(1);
//Print the philospher number, its thread ID and the number of the forks it uses for
eating printf("Philosopher %d with ID %ld eats using forks %d and %d\n", *i+1,
pthread_self(), *i+1, (*i+4)%5+1);
// This signals the other philospher threads that the bowls are available for
eating signal(&bowls);
// This signals the other philospher threads that these forks are available for
eating and thus other threads are woken up
signal(&forks[*i]);
signal(&forks[(*i+4)%5]);
sched_yield();
}
}
void main() {
int i = 0;
// Initialising the forks (shared variable) semaphores
while(i < 5){
init(&forks[i], 0, 1);
i++;
}
i++;
21CSC202J-OPERATING SYSTEMS LAB
}
i = 0;
// Waits for all the threads to end their execution before
ending while(i < 5) {
pthread_join(phil[i], NULL);
i++;
}}
Output :
USING MONITOR
monitor DP
{
status state[5];
condition self[5];
// Pickup chopsticks
Pickup(int i)
{
// indicate that I’m hungry
state[i] = hungry;
// set state to eating in test()
// only if my left and right neighbors
// are not eating
self[i].wait;
}
// signaling R’s CV
test((i + 1) % 5);
test((i + 4) % 5);
}
test(int i)
{
if (state[(i + 1) % 5] != eating
&& state[(i + 4) % 5] != eating
&& state[i] == hungry) {
// indicate that I’m eating
state[i] = eating;
}
}
init()
{
// Execution of Pickup(), Putdown() and test()
// are all mutually exclusive,
21CSC202J-OPERATING SYSTEMS LAB
Output :
Result :
Successfully executed Mutual Exclusion using semaphore and Monitor.
21CSC202J-OPERATING SYSTEMS LAB
Aim :
Algorithm
Step 1: Start
Step 2: Initialize the mutex, semaphore with value 1
Step 3: Create reader thread, writer thread.
Step 4: Reader Thread:
Lock the mutex
Update numreader;
Check for first reader;
Unlock the mutex;
Perform Read operation; lock the mutex, update numreader.
Check if last reader
Unlock mutex.
Step 5: Writer Thread
Wait on semaphore.
Modify cnt;
Signal Semaphore;
Step 6:combine the results;
Step 7:Destroy semaphore
Step 8 : Stop
Program :
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
sem_t wrt;
pthread_mutex_t
21CSC202J-OPERATING SYSTEMS LAB
mutex; int cnt = 1;
int numreader = 0;
void *writer(void *wno)
{
sem_wait(&wrt);
cnt = cnt*2;
printf("Writer %d modified cnt to %d\n",(*((int )wno)),cnt);
sem_post(&wrt);
}
void *reader(void *rno)
{
// Reader acquire the lock before modifying numreader
pthread_mutex_lock(&mutex);
numreader++;
if(numreader == 1) {
sem_wait(&wrt); // If this id the first reader, then it will block the
writer }
pthread_mutex_unlock(&mutex);
// Reading Section
printf("Reader %d: read cnt as %d\n",*((int *)rno),cnt);
// Reader acquire the lock before modifying numreader
pthread_mutex_lock(&mutex);
numreader--;
if(numreader == 0) {
sem_post(&wrt); // If this is the last reader, it will wake up the
writer. }
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t read[10],write[5];
pthread_mutex_init(&mutex, NULL);
sem_init(&wrt,0,1);
int a[10] = {1,2,3,4,5,6,7,8,9,10}; //Just used for numbering the producer and consumer
21CSC202J-OPERATING SYSTEMS LAB
return 0;
}
Output:
Result:
Thus Successfully provided a solution to Reader – Writer using mutex and semaphore.
21CSC202J-OPERATING SYSTEMS LAB
Description:
The dining – philosophers problem is considered a classic synchronization problem because it
is an example of a large class of concurrency – control problems. It is a simple representation
of the need to allocate several resources among several processes in a deadlock-free and
starvation- free manner. Consider five philosophers who spend their lives thinking and eating.
The philosophers share a circular table surrounded by five chairs, each belonging to one
philosopher. In the center of the table is a bowl of rice, and the table is laid with five single
chopsticks. When a philosopher thinks, she does not interact with her colleagues. From time to
time, a philosopher gets hungry and tries to pick up the two chopsticks that are closest to her
(the chopsticks that are between her and her left and right neighbours). A philosopher may pick
up only one chopstick at a time. Obviously, she cam1ot pick up a chopstick that is already in
the hand of a neighbour. When a hungry philosopher has both her chopsticks at the same time,
she eats without releasing her chopsticks. When she is finished eating, she puts down both of
her chopsticks and starts thinking again. The dining-philosophers problem may lead to a
deadlock situation and hence some rules have to be framed to avoid the occurrence of
deadlock.
Algorithm:
Step1: Create a file named philosoher.c using “nano” command.
Step2: initiliaze the all header files
Step3:declare and defined the function of pickup_fork(),test()eat (),think() and neighbor() and left and right
neighbor ().
Step 4: set the philosopher max5 ,meal max 10
Step5: write coding to state the philosphers and pthread identifiers
Step6.if the is state!=eating the it will be in wait state. Else its calls mutex_unlock() . Step7.
Write the coding for display the result of philosopher and meal state and stop the thread Step8:
Compile the file using the given command “gcc philosoher.c -o philosoher -pthread”. Step 9:
use “./philosoher 10” to run the code .
Step 10: stop the program
21CSC202J-OPERATING SYSTEMS LAB
Program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
//Function declarations
void *pickup_forks(void * philosopher_number); void *return_forks(void *
philosopher_number); void test(int philosopher_number); int
left_neighbor(int philosopher_number); int right_neighbor(int
philosopher_number); double think_eat_time(void);
void think(double think_time);
void eat(double eat_time);
//Constants to be used in the program.
#define PHILOSOPHER_NUM 5
#define MAX_MEALS 10
#define MAX_THINK_EAT_SEC 3
//States of philosophers.
enum {THINKING, HUNGRY, EATING} state[PHILOSOPHER_NUM];
//Array to hold the thread identifiers.
pthread_t philos_thread_ids[PHILOSOPHER_NUM];
//Mutex lock.
pthread_mutex_t mutex;
//Condition variables.
pthread_cond_t cond_vars[PHILOSOPHER_NUM];
//Initialize arrays.
int i;
for(i = 0; i < PHILOSOPHER_NUM; i++){
21CSC202J-OPERATING SYSTEMS LAB
state[i] = THINKING;
pthread_cond_init(&cond_vars[i], NULL);
meals_eaten[i] = 0;
}
//Initialize the mutex lock.
pthread_mutex_init(&mutex, NULL);
//Join the threads.
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
pthread_join(philos_thread_ids[i], NULL);
}
//Create threads for the philosophers.
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
pthread_create(&philos_thread_ids[i], NULL, pickup_forks, (void
*)&i); }
sleep(run_time);
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
pthread_cancel(philos_thread_ids[i]);
}
//Print the number of meals that each philosopher ate.
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
printf("Philosopher %d: %d meals\n", i, meals_eaten[i]);
}
}
return 0;
}
void *pickup_forks(void * philosopher_number)
{
int loop_iterations = 0;
int pnum = *(int *)philosopher_number;
while(meals_eaten[pnum] < MAX_MEALS)
{
printf("Philosoper %d is thinking.\n", pnum);
think(think_eat_time());
pthread_mutex_lock(&mutex);
state[pnum] = HUNGRY;
test(pnum);
while(state[pnum] != EATING)
{
pthread_cond_wait(&cond_vars[pnum], &mutex);
}
pthread_mutex_unlock(&mutex);
(meals_eaten[pnum])++;
21CSC202J-OPERATING SYSTEMS LAB
return_forks((philosopher_number));
loop_iterations++;
}
}
void *return_forks(void * philosopher_number)
{
pthread_mutex_lock(&mutex);
int pnum = *(int *)philosopher_number;
state[pnum] = THINKING;
test(left_neighbor(pnum));
test(right_neighbor(pnum));
pthread_mutex_unlock(&mutex);
}
int left_neighbor(int philosopher_number)
{
return ((philosopher_number + (PHILOSOPHER_NUM - 1)) %
5); }
int right_neighbor(int philosopher_number)
{
return ((philosopher_number + 1) % 5);
}
void test(int philosopher_number)
{
if((state[left_neighbor(philosopher_number)] != EATING) &&
(state[philosopher_number] == HUNGRY) &&
(state[right_neighbor(philosopher_number)] != EATING))
{
state[philosopher_number] = EATING;
pthread_cond_signal(&cond_vars[philosopher_number]);
}
}
double think_eat_time(void)
{
return ((double)rand() * (MAX_THINK_EAT_SEC - 1)) / (double)RAND_MAX +
1; }
void think(double think_time)
{
sleep(think_time);
}
Output:
Result:
Thus Successfully implemented the concepts of Dining Philosophers Problem.
21CSC202J-OPERATING SYSTEMS LAB
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
n-Number of process,
m-number of resource types.
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.
9. or not if we allow the request.
10. stop the program.
11. end
Banker’s Algorithm
#include <stdio.h>
int m, n, i, j, al[10][10], max[10][10], av[10], need[10][10], temp, z, y, p,
k; void main()
{
printf("\n Enter no of processes : ");
scanf("%d", &m); // enter numbers of processes
printf("\n Enter no of resources : ");
scanf("%d", &n); // enter numbers of resources
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("\n Enter instances for al[%d][%d] = ", i,j); // al[][] matrix is for allocated
instances scanf("%d", &al[i][j]);
al[i][j]=temp;
}
21CSC202J-OPERATING SYSTEMS LAB
}
for (i = 0; i < m;
i++) {
for (j = 0; j < n; j++) {printf("\n Enter instances for max[%d][%d] = ", i,j); // max[][]
matrix is for max instances
scanf("%d", &max[i][j]);
}
}
for (i = 0; i < n; i++) {
printf("\n Available Resource for av[%d] = ",i); // av[] matrix is for available instances
scanf("%d", &av[i]);
}
// Print allocation values
printf("Alocation Values :\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {printf(" \t %d", al[i][j]); // printing allocation matrix
}
printf("\n");
}
printf("\n\n");
O M oA R cP S D| 2 81 1 40 20
lO M oA R cP S D| 2 81 1 40 20
Aim :
Description:
1. FCFS Scheduling Algorithm :
Given n processes with their burst times, the task is to find average waiting time and
average turn around time using FCFS scheduling algorithm. First in, first out (FIFO), also known
as first come, first served (FCFS), is the simplest scheduling algorithm. FIFO simply queues
processes in the order that they arrive in the ready queue. In this, the process that comes first will
be executed first and next process starts only after the previous gets fully executed. Here we are
considering that arrival time for all processes is 0. 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
Algorithm:
Step 1. Input the processes along with their burst time (bt).
Step 2. Find waiting time (wt) for all processes.
Step 3. As first process that comes need not to wait so waiting time for process 1 will be 0 i.e. wt[0] =
0.
Step 4. Find waiting time for all other processes i.e. for process i -> wt[i] = bt[i-1] + wt[i-1] Step 5.
Find turnaround time = waiting_time + burst_time for all processes.
Step 6. Find average waiting time = total_waiting_time / no_of_processes
Step 7. Similarly, find average turnaround time = total_turn_around_time / no_of_processes. Input :
Processes Numbers and their burst times Output : Process-wise burst-time, waiting-time and
turnaround-time Also display Average-waiting time and Average-turnaround-time
Program :
FCFS Scheduling
#include <stdio.h>
typedef struct fcfs
{
int process; //Process
Number int burst; //Burst
Time
int arrival; //Arrival Time
int tat; //Turn Around
Time int wt; //Waiting
Time
}fcfs;
int sort(fcfs [], int);
int main()
{
int n, i, temp = 0, AvTat = 0, AvWt = 0;
printf ("Enter the number of processes: ");
21CSC202J-OPERATING SYSTEMS LAB
temp = tct[i];
//Bubble Sort
int sort(fcfs arr[], int n)
{
int i, j;
fcfs k;
{
//Sorting the processes according to their arrival time
if (arr[i].arrival > arr[j].arrival)
{
k = arr[i];
arr[i] = arr[j];
arr[j] = k;
}
}
}
return 0;
}
lO M oA R cP S D| 2 81 1 40 20
Output
SJF Scheduling
#include <stdio.h>
int main()
{
int A[100][4]; // Matrix for storing Process Id, Burst
// Time, Average Waiting Time & Average
// Turn Around
Time. int i, j, n, total = 0,
index, temp; float avg_wt,
21CSC202J-OPERATING SYSTEMS LAB
avg_tat;
printf("Enter number of process: ");
scanf("%d", &n);
printf("Enter Burst Time:\n");
// User Input Burst Time and alloting Process
Id. for (i = 0; i < n; i++) {
printf("P%d: ", i + 1);
scanf("%d",
&A[i][1]); A[i][0]
= i + 1;
}
// Sorting process according to their Burst
Time. for (i = 0; i < n; i++) {
index = i;
for (j = i + 1; j < n; j++)
if (A[j][1] < A[index][1])
index = j;
temp = A[i][1];
A[i][1] = A[index][1];
A[index][1] = temp;
temp = A[i][0]; A[i][0] = A[index][0]; A[index][0] = temp; }
A[0][2] = 0;
lO M oA R cP S D| 2 81 1 40 20
// Calculation of Waiting Times for
(i = 1; i < n; i++) {
A[i][2] = 0;
for (j = 0; j < i; j++)
A[i][2] += A[j][1];
total += A[i][2];
}
avg_wt = (float)total / n;
total = 0;
printf("P BT WT TAT\n");
// Calculation of Turn Around Time and printing the
// data.
for (i = 0; i < n; i++) {
A[i][3] = A[i][1] + A[i][2];
total += A[i][3];
printf("P%d %d %d %d\n", A[i][0],
A[i][1], A[i][2], A[i][3]);
}
avg_tat = (float)total / n;
21CSC202J-OPERATING SYSTEMS LAB
lO M oA R cP S D| 2 81 1 40 20
Aim :
To study the concepts of Priority and Round Robin Scheduling
Description
Priority Based Scheduling
Priority Scheduling is a method of scheduling processes based on priority. In this method, the
scheduler selects the tasks to work as per the priority. Priority scheduling also helps OS to
involve priority assignments. The processes with higher priority should be carried out first,
whereas jobs with equal priorities are carried out on a round-robin or FCFS basis. Priority can
be decided based on memory requirements, time requirements, etc. To calculate the average
waiting time in the priority algorithm, sort the burst times according to their priorities and
then calculate the average waiting time of the
processes. The waiting time of each process is obtained by summing up the burst
times of all the previous processes.
Round-Robin Scheduling
Round robin is the oldest, simplest scheduling algorithm. The name of this algorithm comes
from the round-robin principle, where each person gets an equal share of something in turn. It
is mostly used for scheduling algorithms in multitasking. This algorithm method helps for
starvation free execution of processes.To aim is to calculate the average waiting time. There
will be a time slice, each process should be executed within that time-slice and if not it will go
to the waiting state so first check whether the burst time is less than the time-slice. If it is less
than, it assign the waiting time to the sum of the total times. If it is greater than the burst-time
then subtract the time slot from the actual burst time and increment it by time-slot and the
loop continues until all the processes are completed.
Step 3: For each process in the ready Q, assign the process id and accept the CPU burst
time Step 4: Sort the ready queue according to the priority number.
Step 5: Set the waiting of the first process as ̳0‘ and its burst time as its turnaround time
Step 6: Arrange the processes based on process priority
Step 7: For each process in the Ready Q calculate
Step 8: for each process in the Ready Q calculate
a) Waiting time(n)= waiting time (n-1) + Burst time (n-1)
b) Turnaround time (n)= waiting time(n)+Burst time(n)
Step 9: Calculate
c) Average waiting time = Total waiting Time / Number of process
d) Average Turnaround time = Total Turnaround Time / Number of process Print the
results in an order.
Step10: Stop
Program :
Priority Scheduling
#include<stdio.h>
#define max 10
int main()
{
int
i,j,n,bt[max],p[max],wt[max],tat[max],pr[max],total=0,p
os,temp; float avg_wt,avg_tat;
printf("Enter Total Number of Process:");
scanf("%d",&n);
printf("\nEnter Burst Time and Priority For ");
for(i=0;i<n;i++)
{
printf("\nEnter Process %d: ",i+1);
scanf("%d",&bt[i]);
scanf("%d",&pr[i]);
p[i]=i+1;
}
for(i=0;i<n;i++)
{ pos=i;
for(j=i+1;j<n;j++)
{
21CSC202J-OPERATING SYSTEMS LAB
if(pr[j]<pr[pos])
pos=j;
} temp=pr[i];
pr[i]=pr[pos];
pr[pos]=temp;
temp=bt[i];
bt[i]=bt[pos];
bt[pos]=temp;
temp=p[i];
p[i]=p[pos];
p[pos]=temp;
} wt[0]=0;
for(i=1;i<n;i++)
{ wt[i]=0;
for(j=0;j<i;j++)
wt[i]+=bt[j];
total+=wt[i];
}
avg_wt=total/n; lO M oA R cP S D| 2 81 1 40 20
total=0;
Output :
lO M oA R cP S D| 2 81 1 40 20
Program
#include<stdio.h>
int main()
21CSC202J-OPERATING SYSTEMS LAB
{
//Input no of processed
int n;
printf("Enter Total Number of Processes:");
scanf("%d", &n);
int wait_time = 0, ta_time = 0, arr_time[n], burst_time[n],
temp_burst_time[n]; int x = n;
Output :
Result :
Aim :
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.
Algorithm:
Step 1. Start the process
Step 2. Read number of pages n
Step 3. Read number of page frames f
Step 4. Read page values into an array a[i]
Step 5. Initialize avail[i]=0 to check page hit
Step 6. Replace the page with circular queue, while re-placing check page availability
in the frame
Place avail[i]=1 if page is placed in the frame Count page faults
Step 7. Print the results.
Step 8. Stop the process.
Program :
#include <stdio.h>
int a[100],b[100],i,n,z,f,j,pf,h,temp;
void main(){
printf("\nEnter the no. of pages : "); // no. of page referencing
scanf("%d",&n);
printf("\nEnter the size of frame : "); // no. of page frames
scanf("%d",&f);
printf("\n Enter the pages value :\n"); // values of page
referencing for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
21CSC202J-OPERATING SYSTEMS LAB
printf("\n"); lO M oA R cP S D| 2 81 1 40 20
}
Output : Result :
Successfully implemented page replacement using FIFO algorithm
lO M oA R cP S D| 2 81 1 40 20
Aim :
Algorithm:
Step 1: Start
Step 2: Initialize memory for the frames and stack arrays.
Step 3: Get Input- The number of frames and the reference string are taken as
input. Step 4: LRU Algorithm:
• If the page is not found, use an empty frame if available or replace the least
recently used page.
• Page faults are counted, and the current state of frames and page fault status
are printed for each request.
Step 5: Prints the total number of requests, page faults, and page hits.
Step 6: Stop
Program :
LRU
#include <stdio.h>
#include <stdlib.h>
int main() {
int capacity, num_requests, page_faults = 0;
int *frames, *stack, *reference_string;
printf("\nString|Frame →\t");
for (int i = 0; i < capacity; i++) {
printf("%d ", i);
}
printf("Fault\n ↓\n");
break;
}
}
break;
}
if (frames[j] == -1 && empty_frame == -1)
{ empty_frame = j;
}
}
if (!found) {
if (empty_frame != -1) {
// If there's an empty frame, use it
frames[empty_frame] = page;
stack[empty_frame] = empty_frame; } else {
// Replace the least recently used page int
lru_index = stack[0];
frames[lru_index] = page;
// Shift stack elements
for (int j = 0; j < capacity - 1; j++) { stack[j]
= stack[j + 1];
}
stack[capacity - 1] = lru_index;
}
page_faults++;
printf(" %d\t\t", page);
for (int j = 0; j < capacity; j++) {
if (frames[j] != -1) {
printf("%d ", frames[j]);
} else {
printf(" ");
}
}
printf(" Yes\n");
} else {
printf(" %d\t\t", page);
for (int j = 0; j < capacity; j++) {
if (frames[j] != -1) {
printf("%d ", frames[j]);
} else {
printf(" ");
}
}
printf(" No\n");
21CSC202J-OPERATING SYSTEMS LAB
}
}
Output :
Algorithm:
LFU
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int page;
int freq;
int time;
} Page;
printf("\nString|Frame →\t");
for (int i = 0; i < capacity; i++) {
printf("%d ", i);
}
printf("Fault\n ↓\n");
if (!found) {
if (index != -1) {
frames[index].page = page;
frames[index].freq = 1;
frames[index].time = i;
} else {
int min_freq = frames[0].freq, min_time = frames[0].time; index =
0;
frames[index].page = page;
frames[index].freq = 1;
frames[index].time = i;
}
faults++;
printf(" %d\t\t", page);
for (int j = 0; j < capacity; j++) {
if (frames[j].page != -1) {
printf("%d ", frames[j].page);
21CSC202J-OPERATING SYSTEMS LAB
} else {
printf(" ");
}
}
printf(" Yes\n");
} else {
printf(" %d\t\t", page);
for (int j = 0; j < capacity; j++) {
if (frames[j].page != -1) {
printf("%d ", frames[j].page);
} else {
printf(" ");
}
}
printf(" No\n");
}
}
int main() {
int capacity, n;
int pages[n];
printf("Enter the reference string: ");
for (int i = 0; i < n; i++) {
scanf("%d", &pages[i]);
}
return 0;
}
Output
21CSC202J-OPERATING SYSTEMS LAB
Result :
lO M oA R cP S D| 28114020 l
O
Successfully implemented page replacement using LRU and LFU algorithms.
1
1
4
Mo AR cP SD | 0
2
2
0
8
Aim :
To implement and study Best fit and Worst fit memory management policies in C.
Description:
The Best Fit algorithm is a type of memory management scheme used in various
computing contexts, particularly in dynamic memory allocation. It is designed to
manage free memory blocks efficiently by allocating the smallest available block of
memory that is large enough to satisfy the request.
Maintain a list of free memory blocks with their sizes and starting addresses.
When a memory request is made, the algorithm searches the list of free blocks to find
the smallest block that is large enough to fulfill the request.
This search involves checking each free block and keeping track of the smallest block
that fits the requested size.
Once the smallest suitable block is found, the requested memory is allocated from this
block.
If the block is larger than the requested size, it is split into two parts: one part to satisfy
the request and another part that remains free.
When a memory block is freed, it is added back to the list of free blocks. Adjacent
free blocks are usually merged to form larger blocks, reducing fragmentation
• Block 1: 100 KB
• Block 2: 500 KB
• Block 3: 200 KB
• Block 4: 300 KB
If a request for 210 KB of memory is made, the Best Fit algorithm will select Block 4
(300 KB) since it is the smallest block that can satisfy the request. Block 4 will then be
split into a 210 KB allocated block and a 90 KB free block.
Algorithm:
Step 1: Start
Step 2: Define function for memory blocks
Step 3: Initialize the list of memory blocks
Step 4: Allocate memory using best fit algorithm
-Find the best fit block- If no suitable block is found, allocation fails
21CSC202J-OPERATING SYSTEMS LAB
Program :
# Function to allocate memory to
blocks
# as per Best fit algorithm
def bestFit(blockSize, m, processSize,
n):
# Stores block id of the block
# allocated to a
process allocation
= [-1] * n
# pick each process and find suitable
# blocks according to its size ad
# assign to it
for i in range(n):
# Find the best fit block for
# current process
bestIdx = -1
for j in range(m):
if blockSize[j] >= processSize[i]:
if bestIdx == -1:
bestIdx = j
elif blockSize[bestIdx] > blockSize[j]:
bestIdx = j
# If we could find a block for
# current process
if bestIdx != -1:
# allocate block j to p[i] process
allocation[i] = bestIdx
# Reduce available memory in this block.
blockSize[bestIdx] -= processSize[i]
print("Not Allocated")
# Driver code
if name == ' main ':
print("Enter the Process Size")
l=input()
blockSize = [100, 500, 200, 300, 600]
processSize = [212, 417, 112, 426]
m = len(blockSize)
n = len(processSize)
bestFit(blockSize, m, processSize, n)
Output :
Program :
# to any process lO M oA R cP S D| 2 81 1 40 20
allocation = [-1] * n
# pick each process and find suitable
blocks # according to its size ad assign to
it for i in range(n):
# Find the best fit block for
# current process wstIdx = -1
for j in range(m):
if blockSize[j] >= processSize[i]:
if wstIdx == -1:
wstIdx = j
elif blockSize[wstIdx] < blockSize[j]:
wstIdx = j
# If we could find a block for
# current process
if wstIdx != -1:
# Driver code
if name == ' main ':
print("Enter the Process Size")
l=input()
blockSize = [100, 500, 200, 300, 600]
processSize = [212, 417, 112, 426]
m = len(blockSize)
n = len(processSize)
worstFit(blockSize, m, processSize,
n) lO M oA R cP S D| 2 81 1 40 20
Output :
Result :
Successfully implemented and studied Best fit and Worst fit memory
management policies in C.
lO M oA R cP S D| 2 81 1 40 20
Aim :
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.
Algorithm:
Step 1: Start
Step 2: Prompt the user to enter the number of I/O requests (n).
Step 3: Prompt the user to enter the initial position of the disk arm (hp). Step 4:
Validate that the initial position is within the range of total cylinders (200). Step
5: Prompt the user to enter the positions to visit (requests).
Step 6: FCFS (First-Come, First-Served) Disk Scheduling
▪ Initialize time to 0 and pos to hp.
▪ For each request, push the absolute difference between position and
request along with the request itself onto a heap.
▪ Pop the heap to get the request with the smallest seek time.
o Initialize time to 0, pos to hp, end to the maximum value in requests, and
start to the minimum value in requests.
o Seek from pos to end:
▪ For each position from pos to end, if the position is in requests, add
the absolute difference between pos and the position to time,
update pos, and remove the position from requests.
o Add the absolute difference between pos and start to time, and update pos
to start.
o Seek from start to hp:
▪For each position from start to hp, if the position is in requests, add
the absolute difference between pos and the position to time,
update pos, and remove the position from requests.
o Calculate average seek time as time / n.
o Return the average seek time.
Step 12: Main Execution:
o Prompt user to provide input values for the number of I/O requests, initial
disk arm position, and request positions.
o Call each disk scheduling function (FCFS, SSTF, SCAN, C-SCAN,
LOOK, C-LOOK) with the provided input and print the average seek
times.
o Print a thank you message.
Step 13: Stop
Program :
from heapq import *
# hp is initial head position
# and requests is the list of requests
# no of cylinders is 200 def
FCFS(hp,requests):
time = 0
n = len(requests)
pos = hp
for request in requests:
time += abs(request-pos)
pos = request
print(" ",pos," seeked")
# calculate average seek time
avg_seek_time = time / n
return avg_seek_time
# Shortest Seek Time First
def SSTF(hp,reqs):
requests = reqs.copy()
time = 0
position = hp
n = len(requests)
heap=[]
while len(requests)>0:
21CSC202J-OPERATING SYSTEMS LAB
lO M oA R cP S D| 2 81 1 40 20
for r in requests:
heappush(heap,(abs(position-r),r))
x=heappop(heap)[1]
time+=abs(position-x)
position=x
print(" ",x," seeked")
requests.remove(x)
heap=[]
# calculate average seek time
avg_seek_time = time/n
return avg_seek_time
def SCAN(hp,reqs):
requests = reqs.copy()
pos = hp
time = 0
end=200
start=0
#seek from curr_pos to end
which is 200 for i in
range(pos,end+1):
if i in requests:
time+=abs(pos-i)
pos=i
print(" ",i," seeked")
requests.remove(i)
time+=abs(pos-end)
pos=end
#seek back to start
for i in range(end,start-1,-1): if i in requests: print(time)
time+=abs(pos-i) # calculate average seek time avg_seek_time =
# print(time) time/n return avg_seek_time
pos=i def C_SCAN(hp,reqs):
print(" ",i," seeked") requests = reqs.copy()
requests.remove(i) pos = hp
time = 0 range(pos,end+1):
end=200 if i in requests:
start=0 time+=abs(pos-i)
#seek from curr_pos to end which is 200 for i in lO M oA R cP S D| 2 81 1 40 20
pos=i
print(" ",i," seeked")
requests.remove(i)
time+=abs(pos-end) pos=i
pos=end print(" ",i," seeked")
#seek to hp from start requests.remove(i)
for i in range(start,hp+1): if i in requests: # calculate average seek time
time+=abs(pos-i) lO M oA R cP S D| 2 81 1 40 20
if i in requests: time+=abs(pos-i)
pos=i
print(" ",i," seeked")
requests.remove(i)
print(time)
# calculate average seek time avg_seek_time = time/n return
avg_seek_time def C_LOOK(hp,reqs): requests = reqs.copy() pos
= hp
time = 0 end=max(requests)
start=min(requests)
#seek from curr_pos to max of list for i in
range(pos,end+1): if i in requests:
time+=abs(pos-i) pos=i
print(" ",i," seeked")
requests.remove(i)
time+=abs(pos-start)
pos=start
#seek to hp from start
for i in range(start,hp+1):
if i in requests:
time+=abs(pos-i)
pos=i
print(" ",i," seeked")
requests.remove(i)
21CSC202J-OPERATING SYSTEMS LAB
Output :
Result :
Algorithms.
Aim :
To implement and study Sequential and Indexed File Allocation
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.
Program :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TOTAL_DISK_BLOCKS 32
#define TOTAL_DISK_INODES 8
#ifndef MAX
#define MAX 15
#endif
int blockStatus[TOTAL_DISK_BLOCKS]; // free = 0
21CSC202J-OPERATING SYSTEMS LAB
int blockStart;
struct file_table { char fileName[20];
int startBlock;
int fileSize;
int allotStatus;
};
struct file_table fileTable[TOTAL_DISK_BLOCKS - TOTAL_DISK_INODES];
lO M oA R cP S D| 2 81 1 40 20
Output :
lO M oA R cP S D| 2 81 1 40 20