Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
21 views

Operating System Lab Manual

Uploaded by

harishawskit
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views

Operating System Lab Manual

Uploaded by

harishawskit
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 65

21CSC202J-OPERATING SYSTEMS LAB

21CSC202J - OPERATING SYSTEMS

LAB MANUAL

II YEAR / III Semester

Academic Year: 2024-2025 ODD SEMESTER

FACULTY OF ENGINEERING AND TECHNOLOGY SRM


INSTITUTE OF SCIENCE AND TECHNOLOGY

RAMAPURAM CHENNAI- 600 089


21CSC202J-OPERATING SYSTEMS LAB

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

4 Mutual Exclusion using semaphore and monitor

5 Reader-Writer problem

6 Dining Philosopher problem

7 Bankers Algorithm for Deadlock avoidance

8 FCFS and SJF Scheduling

9 Priority and Round robin scheduling

10 FIFO Page Replacement Algorithm

11 LRU and LFU Page Replacement Algorithm

12 Best fit and Worst fit memory management policies

13 Disk Scheduling algorithm

14 Sequential and Indexed file Allocation

15 File organization schemes for single level and two level directory

21CSC202J-OPERATING SYSTEMS LAB


Ex No. 1a OPERATING SYSTEM INSTALLATION

Linux operating system can be installed as either dual OS in your system or you
can install through a virtual machine (VM).

Installation of Ubuntu in yourWindows OS through a Virtual machine

Steps
1. Download VMware Player or Workstation recent version.

2. Download Ubuntu LTS recent version.

3. Install VM ware Player in your host machine.


4. Open VMware Workstation and click on "New Virtual Machine".

5. Select "Typical (recommended)" and click "Next".

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.

14. On the completion of installation, login to the system


21CSC202J-OPERATING SYSTEMS LAB

Turn Windows features On or Off


21CSC202J-OPERATING SYSTEMS LAB
Windows subsystem for linux then press Ok

restart the PC to apply the changes

Choose Microsoft Store and search for Ubuntu and Install it


21CSC202J-OPERATING SYSTEMS LAB
21CSC202J-OPERATING SYSTEMS LAB

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:

Finally completed installation of Ubuntu in windows 10- 64 bits successfully.


21CSC202J-OPERATING SYSTEMS LAB
Ex. No. 1B BASIC LINUX COMMANDS Date :

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

b) Working with Files


1. ls �� list files in the present working directory
ls –l �� list files with detailed information (long list)
ls –a �� list all files including the hidden files

2. cat > f1 �� to create a file (Press ^d to finish typing)

3. cat f1 �� display the content of the file f1

4. wc f1 �� list no. of characters, words & lines of a file f1


wc –c f1 �� list only no. of characters of file f1
wc –w f1 �� list only no. of words of file f1
wc –l f1 �� list only no. of lines of file f1

5. cp f1 f2 �� copy file f1 into f2

6. mv f1 f2 �� rename file f1 as f2

7. rm f1 �� remove the file f1

8. head –5 f1 �� list first 5 lines of the file f1


tail –5 f1 �� list last 5 lines of the file f1

c) Working with Directories


1. mkdir elias �� to create the directory elias
2. cd elias �� to change the directory as elias
3. rmdir elias �� to remove the directory elias
4. pwd �� to display the path of the present working directory
5. cd �� to go to the home directory
cd .. �� to go to the parent directory
cd - �� to go to the previous working directory
cd / �� to go to the root directory
d) File name substitution
1. ls f? �� list files start with ‘f’ and followed by any one character 2. ls *.c �� list files with

extension ‘c’ 3. ls [gpy]et �� list files whose first letter is any one of the character g, p or y and

followed by the word et


4. ls [a-d,l-m]ring �� list files whose first letter is any one of the character from a to d and l to m
and followed by the word ring.
21CSC202J-OPERATING SYSTEMS LAB

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.

ex. cat f1 | more �� list the contents of file f1 screen by screen

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

2. echo $PS1 �� display the prompt string $


3. echo $PS2 �� display the second prompt string ( > symbol by default ) 4. echo $LOGNAME
�� login name
5. echo $PATH �� list of pathname where the OS searches for an executable file

h) File Permission
-- chmod command is used to change the access permission of a file.

Method-1
Syntax : chmod [ugo] [+/-] [ rwxa ] filename

u : user, g : group, o : others


+ : Add permission - : Remove the permission
r : read, w : write, x : execute, a : all permissions
ex. chmod ug+rw f1
adding ‘read & write’ permissions of file f1 to both user and group
members.
Method-2
Syntax : chmod octnum file1

The 3 digit octal number represents as follows


∙ first digit -- file permissions for the user
∙ second digit -- file permissions for the group
∙ third digit -- file permissions for others
Each digit is specified as the sum of following
4 – read permission, 2 – write permission, 1 – execute permission
ex. chmod 754 f1
it change the file permission for the file as follows
∙ read, write & execute permissions for the user ie; 4+2+1 = 7
∙ read, & execute permissions for the group members ie; 4+0+1 = 5 ∙ only read permission for others
ie; 4+0+0 = 4
21CSC202J-OPERATING SYSTEMS LAB
Result:

The above commands are successfully executed and verified.


21CSC202J-OPERATING SYSTEMS LAB
Ex. No. 1C FILTERS and ADMIN COMMANDS Date :

FILTERS

1. cut
▪ Used to cut characters or fileds from a file/input

Syntax : cut -cchars filename


-ffieldnos filename

▪ 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

cut -ddelimitchar -ffileds filname

2. grep
▪ Used to search one or more files for a particular pattern.

Syntax : grep pattern filename(s)

Lines that contain the pattern in the file(s) get displayed


pattern can be any regular expressions
More than one files can be searched for a pattern

-v option displays the lines that do not contain the pattern


-l list only name of the files that contain the pattern
-n displays also the line number along with the lines that matches the pattern

3. sort
▪ Used to sort the file in order

Syntax : sort filename

Sorts the data as text by default


Sorts by the first filed by default
-r option sorts the file in descending order
-u eliminates duplicate lines
-o filename writes sorted data into the file fname
-tdchar sorts the file in which fileds are separated by dchar
-n sorts the data as number
+1n skip first filed and sort the file by second filed numerically

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

21CSC202J-OPERATING SYSTEMS LAB

EX.NO: Process Creation using fork() and Usage of


2 getpid(), getppid(), wait() functions

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

wait() ➔ makes a process wait for other process to


complete Virtual fork
vfork() is similar to fork but both processes shares the same address
space. Program :
• Process creating using fork()

#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

21CSC202J-OPERATING SYSTEMS LAB

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

EX.NO. 3 Multithreading and pthread in C

Aim :

To implement and study Multithreading and pthread in C

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

Multithreading models are three types

· Many to many relationship.


· Many to one relationship.
· One to one relationship.
We must include the pthread.h header file at the beginning of the script to use all the
functions of the pthreads library.

The functions defined in the pthreads library include:

a. pthread_create: used to create a new thread


Syntax:
int pthread_create(pthread_t * thread,const pthread_attr_t * attr, void * (*start_routine)(void
*), void *arg);

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.

c. pthread_join: used to wait for the termination of a thread.


21CSC202J-OPERATING SYSTEMS LAB

Syntax:
int pthread_join(pthread_t th,void **thread_return);

Parameter: This method accepts following parameters:

· 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);

Parameters: This method accepts following parameters:

· t1: the thread id of the first thread


· t2: the thread id of the second thread
Algorithm:
Step: 1 Start
Step: 2 Read Input File
Step: 3 Initialize Threads. Max of 4 threads
Step: 4 Execute each thread.
Step: 5 Combine results from each thread.
Step: 6 Display the total sum.
Step: 7 Stop

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;

void* sum_array(void* arg)


{
int thread_part = arraypart++;
21CSC202J-OPERATING SYSTEMS LAB

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];

for (int i = 0; i < MAX_THREAD; i++)


{
pthread_create(&threads[i], NULL, sum_array,
(void*)NULL); }

// joining threads
for (int i = 0; i < MAX_THREAD; i++)
{
pthread_join(threads[i], NULL);
}

// print each thread


for (int i = 0; i < MAX_THREAD; i++)
{
printf("Thread %d Sum is : %d \n",i, sum[i]);
} for (int i = 0; i < MAX_THREAD; i++) {
// adding the 4 parts total_sum += sum[i];
int total_sum = 0; }
lO M oA R cP S D| 2 81 1 40 20

printf("\nTotal Sum is : %d \n",total_sum);

}
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

char line [5]; /* line size */

int i=0;

printf("Reading file: ");


fputs(file_name,stdout);
printf("\n");
while ( fgets ( line, sizeof line, fp) != NULL ) /* read a line
*/ {
if (i < 1000)
{
array[i]=atoi(line);
}

i++;
} fclose(fp);
lO M oA R cP S D| 2 81 1 40 20

printf("Reading file Complete, integers stored in

array.\n\n"); }

int main(int argc, char* argv[])


{
if (argc != 2) {
fprintf(stderr,"usage: a.out <file name>\n");
/*exit(1);*/
return -1;
}
readfile(argv[1]);
//Debug code for testing only
testSum();
return 0;
}
Output :

21CSC202J-OPERATING SYSTEMS LAB


Result :
Thus the Program Successfully implemented and studied
Multithreading and pthread in C
lO M oA R cP S D| 2 81 1 40 20

21CSC202J-OPERATING SYSTEMS LAB

EX.NO. 4 Mutual Exclusion using semaphore and monitor

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.

SYSTEM V SEMAPHORE SYSTEM CALLS

Include the following header files for System V semaphore

<sys/ipc.h>, <sys/sem.h>, <sys/types.h>

To create a semaphore array,

int semget(key_t key, int nsems, int semflg)

key ➔ semaphore id

nsems ➔ no. of semaphores in the semaphore array

semflg ➔ IPC_CREATE|0664 : to create a new semaphore

IPC_EXCL|IPC_CREAT|0664 : to create new semaphore and the

call fails if the semaphore already exists To


perform operations on the semaphore sets viz., allocating resources, waiting for the resources or
freeing the resources,

int semop(int semid, struct sembuf *semops, size_t nsemops)

semid ➔ semaphore id returned by semget()


nsemops ➔ the number of operations in that
array

semops ➔ The pointer to an array of operations to be performed on


the semaphore set. The structure is as follows

struct sembuf {

unsigned short sem_num; /* Semaphore set num */ short


sem_op; /* Semaphore operation */ short sem_flg; /*Operation
flags, IPC_NOWAIT, SEM_UNDO */

};
21CSC202J-OPERATING SYSTEMS LAB
Algorithm:

Step1: start the program

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.

Step6: stop the program..

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 {

// Semaphore mutual exclusion variable


pthread_mutex_t mutex;
// Semaphore count variable
int cnt;
// Semaphore conditonal variable
pthread_cond_t conditional_variable;
}
my_semaphore;

// Function to initialise the semaphore variables


21CSC202J-OPERATING SYSTEMS LAB

int init(my_semaphore *sema, int pshared, int val) {


// The case when pshared == 1 is not implemeted as it was not required because the
philosphers are implemented using threads and not processes.
lO M oA R cP S D| 2 81 1 40 20
if(pshared == 1){
printf("Cannot handle semaphores shared between processes!!!
Exiting\n"); return -1;
}

// Initialisng the semaphore conditonal variable


pthread_cond_init(&sema->conditional_variable, NULL);

// Initialisng the semaphore count variable


sema->cnt = val;

// Initialisng the semaphore mutual exclusion variable


pthread_mutex_init(&sema->mutex, NULL);

return 0;
}

int signal(my_semaphore *sema) {

//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;

// This wakes up one waiting thread


if (sema->cnt)

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

// This releases the mutex

21CSC202J-OPERATING SYSTEMS LAB

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;

// This releases the mutex and threads can access mutex


pthread_mutex_unlock(&sema->mutex);

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;

//Function for the philospher threads to eat


void *eat_food(void *arg) {
while(1) {
int* i = arg;
// This puts a wait condition on the bowls to be used by the current philospher so
that the philospher can access these forks whenever they are free
lO M oA R cP S D| 2 81 1 40 20

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++;
}

// Initialising the bowl (shared variable) semaphore


init(&bowls, 0, 1);
// Declaring the philospher threads
pthread_t phil[5];
i = 0;
// Creating the philospher threads
while(i < 5) {

pthread_create(&phil[i], NULL, eat_food, &philNo[i]);


lO M oA R cP S D| 2 81 1 40 20

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

test(i); 21CSC202J-OPERATING SYSTEMS LAB lO M oA R cP S D| 2 81 1 40 20

// if unable to eat, wait to be signaled if


(state[i] != eating)

self[i].wait;
}

// Put down chopsticks


Putdown(int i)
{
// indicate that I’m thinking
state[i] = thinking;
// if right neighbor R=(i+1)%5 is hungry and
// both of R’s neighbors are not eating, //
set R’s state to eating and wake it up by

// 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;

// signal() has no effect during Pickup(),


// but is important to wake up waiting

// hungry philosophers during Putdown()


self[i].signal();

}
}
init()
{
// Execution of Pickup(), Putdown() and test()
// are all mutually exclusive,
21CSC202J-OPERATING SYSTEMS LAB

// i.e. only one at a time can be executing


for
i = 0 to 4
// Verify that this monitor-based solution is
// deadlock free and mutually exclusive in that
// no 2 neighbors can eat simultaneously
state[i] = thinking;
}
}

Output :

Result :
Successfully executed Mutual Exclusion using semaphore and Monitor.
21CSC202J-OPERATING SYSTEMS LAB

EX.NO. 5 Reader-Writer problem

Aim :

To study the Reader – Writer problem


Description:
Consider a situation where we have a file shared between many people.
➢ If one of the person tries editing the file, no other person should be reading or writing at the
same time, otherwise changes will not be visible to him/her.
➢ However, if some person is reading the file, then others may read it at the same time.

Precisely in OS, we call this situation the readers-writer, problem.

➢ One set of data is shared among a number of processes


➢ Once a writer is ready, it performs its write. Only one writer may write at a time
➢ If a process is writing, no other process can read it
➢ If at least one reader is reading, no other process can write
➢ Readers may not write and only read

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

for(int i = 0; i < 10; i++) {

pthread_create(&read[i], NULL, (void *)reader, (void *)&a[i]);


}
for(int i = 0; i < 5; i++) {
pthread_create(&write[i], NULL, (void *)writer, (void *)&a[i]);
}
for(int i = 0; i < 10; i++) {
pthread_join(read[i], NULL);
}
for(int i = 0; i < 5; i++) {
pthread_join(write[i], NULL);
}
pthread_mutex_destroy(&mutex);
sem_destroy(&wrt);

return 0;

}
Output:

Result:
Thus Successfully provided a solution to Reader – Writer using mutex and semaphore.
21CSC202J-OPERATING SYSTEMS LAB

EX:NO:6 Dining Philosopher’s Problem


Aim:

To implement and study Dining Philosopher’s Problem

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];

//Array to hold the number of meals eaten for each philosopher.


int meals_eaten[PHILOSOPHER_NUM];

int main(int argc, char *argv[])


{
//Ensure correct number of command line arguments.
if(argc != 2)
{
printf("Please ensure that the command line argument 'run_time' is
passed.\n"); }
else
{
//Set command line argument value to variable run_time;
double run_time = atof(argv[1]);

//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

printf("Philosoper %d is eating meal %d.\n", pnum, meals_eaten[pnum]);


eat(think_eat_time());

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);
}

void eat(double eat_time)


{
sleep(eat_time);
}
21CSC202J-OPERATING SYSTEMS LAB

Output:
Result:
Thus Successfully implemented the concepts of Dining Philosophers Problem.
21CSC202J-OPERATING SYSTEMS LAB

EX:NO:7 Bankers Algorithm for Deadlock avoidance


Aim :
To implement and study Bankers Algorithm for Deadlock Avoidance Problem.

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");

// Print max values


printf("Max Values :\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf(" \t %d", max[i][j]); // printing max matrix
}
printf("\n");
}
printf("\n\n");

// Print need values


printf("Need Values :\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
need[i][j] = max[i][j] - al[i][j]; // calculating need matrix
printf("\t %d", need[i][j]); // printing need matrix
}
printf("\n");
}
p = 1; // used for terminating while loop
y = 0;
while (p != 0) {
for (i = 0; i < m; i++) {
z = 0;
for (j = 0; j < n; j++) {
if (need[i][j] <= av[j] &&
21CSC202J-OPERATING SYSTEMS LAB

(need[i][0] != -1)) { // comparing need with available instance


and // checking if the process is done
// or not
z++; // counter if condition TRUE
}
}
if (z == n) { // if need<=available TRUE for all resources then
condition // is TRUE
for (k = 0; k < n; k++) {
av[k] += al[i][k]; // new work = work + allocated
}
21CSC202J-OPERATING SYSTEMS LAB

printf("\n SS process %d", i); // Print the Process


need[i][0] = -1; // assign -1 if Process done
y++; // cont if process done
}
} // end for loop
if (y == m) { // if all done then
p = 0; // exit while loop
}} // end while printf("\n");
}
Output :

O M oA R cP S D| 2 81 1 40 20

21CSC202J-OPERATING SYSTEMS LAB


Result :

Successfully implemented the concepts of Banker’s Algorithm.

lO M oA R cP S D| 2 81 1 40 20

21CSC202J-OPERATING SYSTEMS LAB

EX:NO:8 FCFS and SJF Scheduling

Aim :

To study the concepts of FCFS and SJF Scheduling

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

scanf ("%d", &n);


fcfs arr[n]; //Array of type
fcfs int tct[n];
for (i = 0; i < n; i++)
{
arr[i].process = i;
printf ("Enter the process %d data\n", arr[i].process);
printf ("Enter CPU Burst: ");
scanf ("%d", &(arr[i].burst));
printf ("Enter the arrival time:
"); scanf ("%d",
&(arr[i].arrival));
}
//Sorting the processes according to their arrival
time sort(arr, n);
printf ("Process\t\tBurst Time\tArrival Time\tTurn Around
Time\tWaiting Time\n");
for (i = 0; i < n; i++)
{
tct[i] = temp + arr[i].burst;
lO M oA R cP S D| 2 81 1 40 20

temp = tct[i];

arr[i].tat = tct[i] - arr[i].arrival;


arr[i].wt = arr[i].tat - arr[i].burst;
AvTat = AvTat + arr[i].tat;
AvWt = AvWt + arr[i].wt;
printf ("%5d\t%15d\t\t%9d\t%12d\t%12d\n", arr[i].process,
arr[i].burst, arr[i].arrival, arr[i].tat, arr[i].wt);
}
printf ("Average Turn Around Time: %d\nAverage Waiting Time:
%d\n", AvTat / n, AvWt / n);
return 0;
}

//Bubble Sort
int sort(fcfs arr[], int n)
{
int i, j;
fcfs k;

for (i = 0; i < n - 1; i++)


{
for (j = i + 1; j < n; j++)
21CSC202J-OPERATING SYSTEMS LAB

{
//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

printf("Average Waiting Time= %f", avg_wt);


printf("\nAverage Turnaround Time= %f", avg_tat);
}
Output :

Result : Implemented the concepts of FCFS and SJF Scheduling in C


successfully.

lO M oA R cP S D| 2 81 1 40 20

21CSC202J-OPERATING SYSTEMS LAB

EX:NO:9 Priority and Round Robin Scheduling

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.

Algorithm: Priority Based Scheduling


Step 1: Start the process
Step 2: Accept the number of processes in the ready Queue
21CSC202J-OPERATING SYSTEMS LAB

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;

printf("\n\nProcess\t\tBurst Time\t\tWaiting Time\t\tTurn


Around Time"); for(i=0;i<n;i++)
{
tat[i]=bt[i]+wt[i];
total+=tat[i];
printf("\n P%d\t\t%d\t\t\t%d\t\t\t\t%d",p[i],bt[i],wt[i],tat[i]);
}
avg_tat=total/n;
printf("\n\nAverage Waiting Time = %.2f",avg_wt);
printf("\nAvg Turn Around Time = %.2f\n",avg_tat);
return 0;
}
21CSC202J-OPERATING SYSTEMS LAB

Output :

lO M oA R cP S D| 2 81 1 40 20

Algorithm:Round Robin Scheduling


Step 1: Start the process
Step 2: Accept the number of processes in the ready Queue and time quantum (or)
time slice
Step 3: For each process in the ready Q, assign the process id and accept the CPU
burst time
Step 4: Calculate the no. of time slices for each process where No. of time slice for
process (n) = burst time process (n)/time slice
Step 5: If the burst time is less than the time slice then the no. of time slices
=1. Step 6: Consider the ready queue is a circular Q, calculate
a) Waiting time for process (n) = waiting time of process(n-1)+ burst time of
process(n-1 ) + the time difference in getting the CPU fromprocess(n-1) b)
Turnaround time for process(n) = waiting time of process(n) + burst time of
process(n)+ the time difference in getting CPU from process(n).
Step 7: Calculate
c) Average waiting time = Total waiting Time / Number of process
d) Average Turnaround time = Total Turnaround Time / Number ofprocess
Step 8: Stop the process

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;

//Input details of processes


for(int i = 0; i < n; i++)
{
printf("Enter Details of Process %d \n", i + 1);
printf("Arrival Time: ");
scanf("%d", &arr_time[i]);
printf("Burst Time: ");
scanf("%d", &burst_time[i]);
temp_burst_time[i] = burst_time[i];
}

//Input time slot


int time_slot;
printf("Enter Time Slot:");
scanf("%d", &time_slot);

//Total indicates total time


//counter indicates which process is executed
int total = 0, counter = 0,i;
printf("Process ID Burst Time Turnaround Time Waiting
Time\n"); for(total=0, i = 0; x!=0; )
{
// define the conditions
if(temp_burst_time[i] <= time_slot && temp_burst_time[i] > 0)
{
total = total + temp_burst_time[i];
temp_burst_time[i] = 0;
counter=1;
}
else if(temp_burst_time[i] > 0)
{ lO M oA R cP S D| 2 81 1 40 20

temp_burst_time[i] = temp_burst_time[i] - time_slot;


total += time_slot;
}
if(temp_burst_time[i]==0 && counter==1)
{
x--; //decrement the process no.
21CSC202J-OPERATING SYSTEMS LAB

printf("\nProcess No %d \t\t %d\t\t\t%d\t\t\t %d", i+1,


burst_time[i], total-arr_time[i], total-arr_time[i]-
burst_time[i]);
wait_time = wait_time+total-arr_time[i]-burst_time[i];
ta_time += total -arr_time[i]; 0
counter =0;
}
if(i==n-1)
{
i=0;
}
else if(arr_time[i+1]<=total)
{
i++;
}
else
{
i=0;
}
}
float average_wait_time = wait_time * 1.0 / n;
float average_turnaround_time = ta_time * 1.0 / n;
printf("\nAverage Waiting Time:%f",
average_wait_time); printf("\nAvg Turnaround
Time:%f", average_turnaround_time); return 0;
} lO M oA R cP S D| 2 81 1 40 20

Output :

Result :

Implemented the concepts of Priority Scheduling and Round Robin


Scheduling in C successfully
21CSC202J-OPERATING SYSTEMS LAB
EX No 10 FIFO Page Replacement Algorithm

Aim :

To implement FIFO page replacement algorithm

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 :

FIFO Page Replacement Algorithm

#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

for(i=0;i<f;i++){ // assign values of page frames 1 innitially


b[i]=-1;
}
i=0;j=0;h=0; // i , j used for loop, h for hit count all initialized to 0
while(i<n){
if(b[i]=-1 && i<f ){ // when frames are empty so for starting
enquee b[i]=a[i];
pf++; // page fault counter
}
else
{
z=0
;
for(j=0;j<f;j++){

if(b[j]==a[i]){ // to check if value already


present h++; // hit counter
}
else{
z++; // if not hit count increment
}
}
if(z==f){ // if no value
matched pf++; // page
fault counter for(j=0;j<f-1;j++){ // shifting
values b[j+1]=tem p;
temp=b[j]; b[j]=b[j+1] ; }
lO M oA R cP S D| 2 81 1 40 20

b[f-1]=a[i]; // insert new values


}
} // end else
printf("\n Current Frame: %d \t %d \t %d \n",b[2],b[1],b[0]); // frames
value for every iteration
i++;
} //end while
printf("\n frame at the end :");
for(i=0;i<f;i++){
printf("\n b[%d] = %d",i,b[i]); // frame values at the end }
printf("\n Page Fault = %d ",pf); // no. of page
faults printf("\n Hit = %d ",h); // no. of hitS
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

21CSC202J-OPERATING SYSTEMS LAB


EX No 11 LRU AND LFU Page Replacement

Aim :

To implement page replacement using LRU and LFU


Description:
LRU replaces the page that has not been used for the longest period of time. The idea
is based on the assumption that pages used recently will likely be used again soon.
Common implementations include using a linked list or a stack where each time a page
is accessed, it is moved to the top. When a page needs to be replaced, the page at the
bottom (least recently used) is chosen.
Assume a system has 3 page slots and the page request sequence is: 1, 2, 3, 1, 4,
5. 1. Load pages 1, 2, 3 → (1, 2, 3)
2. Page 1 accessed again → (2, 3, 1)
3. Page 4 replaces page 2 (LRU) → (3, 1, 4)
4. Page 5 replaces page 3 (LRU) → (1, 4, 5)

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:

• Iterate over each page request

• Checks if the page is already in the frames.

• If the page is found, update the stack to mark it as recently used.

• 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;

21CSC202J-OPERATING SYSTEMS LAB

// Input the number of frames


printf("Enter the number of frames: ");
scanf("%d", &capacity);

// Allocate memory for frames and stack


frames = (int *)malloc(capacity * sizeof(int));
stack = (int *)malloc(capacity * sizeof(int));

// Initialize frames and stack


for (int i = 0; i < capacity; i++) {
frames[i] = -1;
stack[i] = -1;
}

// Input the reference string


printf("Enter the number of requests: ");
scanf("%d", &num_requests);
reference_string = (int *)malloc(num_requests * sizeof(int));
printf("Enter the reference string: ");
for (int i = 0; i < num_requests; i++) {
scanf("%d", &reference_string[i]);
}

printf("\nString|Frame →\t");
for (int i = 0; i < capacity; i++) {
printf("%d ", i);
}
printf("Fault\n ↓\n");

for (int i = 0; i < num_requests; i++) {


int page = reference_string[i];
int found = 0, empty_frame = -1;

// Check if the page is already in frames


for (int j = 0; j < capacity; j++) {
if (frames[j] == page) {
found = 1;
// Move the page to the top of the stack for (int
k = 0; k < capacity; k++) {
if (stack[k] == j) {
for (int l = k; l < capacity - 1; l++) { stack[l] =
stack[l + 1];
}
stack[capacity - 1] = j;
21CSC202J-OPERATING SYSTEMS LAB

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

}
}

printf("\nTotal Requests: %d\nPage Faults: %d\n", num_requests, page_faults);


printf("Page Hit: %d\n", num_requests - page_faults);

// Free allocated memory


free(frames);
free(stack);
free(reference_string);
return 0;
}
lO M oA R cP S D| 2 81 1 40 20

Output :

Algorithm:

LFU
#include <stdio.h>
#include <stdlib.h>

typedef struct {
int page;
int freq;
int time;
} Page;

void LFU(int capacity, int pages[], int n) {


Page frames[capacity];
int faults = 0, hits = 0;

for (int i = 0; i < capacity; i++) {


frames[i].page = -1;
frames[i].freq = 0;
frames[i].time = 0;
}
21CSC202J-OPERATING SYSTEMS LAB

printf("\nString|Frame →\t");
for (int i = 0; i < capacity; i++) {
printf("%d ", i);
}
printf("Fault\n ↓\n");

for (int i = 0; i < n; i++) {


int page = pages[i];
int found = 0, index = -1;

for (int j = 0; j < capacity; j++) {


if (frames[j].page == page) {
found = 1;
frames[j].freq++;
frames[j].time = i;
hits++;
break;
}
if (frames[j].page == -1) {
index = j;
}
}

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;

for (int j = 1; j < capacity; j++) {


if (frames[j].freq < min_freq || (frames[j].freq == min_freq &&
frames[j].time < min_time)) {
min_freq = frames[j].freq;
min_time = frames[j].time;
index = j;
}
}

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");
}
}

printf("\nTotal Requests: %d\nPage Faults: %d\n", n, faults);


printf("Page Hits: %d\n", hits);
}

int main() {
int capacity, n;

printf("Enter the number of frames: ");


scanf("%d", &capacity);

printf("Enter the number of pages: ");


scanf("%d", &n);

int pages[n];
printf("Enter the reference string: ");
for (int i = 0; i < n; i++) {
scanf("%d", &pages[i]);
}

LFU(capacity, pages, n);

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

21CSC202J-OPERATING SYSTEMS LAB


EX:NO:12 Best Fit and Worst Fit Memory Management Policies

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

Consider a system with the following free memory blocks:

• 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

-Allocate memory from the best fit block


- update free block
Step 5: Display the results
Step 6: Stop

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("Process No. Process Size Block no.")


for i in range(n):
print(i + 1, " ", processSize[i],
end = " ") if allocation[i] != -1: print(allocation[i] + 1) else:
lO M oA R cP S D| 2 81 1 40 20

21CSC202J-OPERATING SYSTEMS LAB

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 :

Worst Fit Policy


Algorithm :
Step 1: Start
Step 2: Input memory blocks and processes with sizes.
Step 3: Initialize all memory blocks as free.
Step 4: Start by picking each process and find the minimum block size that can
be assigned to current process i.e., find min(bockSize[1],
blockSize[2],.....blockSize[n]) > processSize[current], if found then assign it to
the current process.
Step 5: If not then leave that process and keep checking the
further processes.
Step 6: Stop

Program :

# Function to allocate memory to blocks as


# per worst fit algorithm
def worstFit(blockSize, m, processSize, n):
# Stores block id of the block
# allocated to a process
# Initially no block is assigned
21CSC202J-OPERATING SYSTEMS LAB

# 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:

# allocate block j to p[i] process


allocation[i] = wstIdx

# Reduce available memory in this block.


blockSize[wstIdx] -= processSize[i]

print("Process No. Process Size


Block no.") for i in range(n):
print(i + 1, " ",
processSize[i], end = " ")
if allocation[i] != -1:
print(allocation[i] + 1)
else:
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)
worstFit(blockSize, m, processSize,
n) lO M oA R cP S D| 2 81 1 40 20

21CSC202J-OPERATING SYSTEMS LAB

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

21CSC202J-OPERATING SYSTEMS LAB


EX No 13 Disk Scheduling Algorithm

Aim :

To implement and study disk scheduling algorithms.

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 in requests:

▪ Add the absolute difference between request and pos to time.

▪ Update pos to request.

▪ Calculate average seek time as time / n.

▪ Return the average seek time.


Step 7: SSTF (Shortest Seek Time First) Disk Scheduling
▪ Initialize time to 0, position to hp, and create a copy of requests.

▪ While there are requests remaining:

▪ 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.

▪ Add the absolute difference between position and the popped


request to time.
▪ Update position to the popped request.

▪ Remove the popped request from requests.


21CSC202J-OPERATING SYSTEMS LAB

▪ Calculate average seek time as time / n.

▪ Return the average seek time.


Step 8: SCAN Disk Scheduling
o Initialize time to 0, pos to hp, end to 200, and start to 0.
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 end to time, and update pos
to end.
o Seek from end to start:
▪For each position from end to start, 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 9: C-SCAN (Circular SCAN) Disk Scheduling
o Initialize time to 0, pos to hp, end to 200, and start to 0.
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 end to time, and update pos
to end.
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 10: LOOK Disk Scheduling:
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 Seek from end to start:
For each position from end to start, 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 11: C-LOOK (Circular LOOK) Disk Scheduling:
21CSC202J-OPERATING SYSTEMS LAB

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

21CSC202J-OPERATING SYSTEMS LAB

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

avg_seek_time = time/n return


avg_seek_time
def LOOK(hp,reqs): requests =
reqs.copy() pos = hp
time = 0 end=max(requests)
start=min(requests)
#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) for i in range(end,start-1,-1):
#seek back to start 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

# calculate average seek time avg_seek_time = time/n return


avg_seek_time lO M oA R cP S D | 2 81 1 40 20

if name ==' main ': print("DISK SCHEDULING:")


print("Provide number of I/O requests")
#n is the number of I/O requests n
= int(input())
print("Provide initial position of disc arm (total
cylinders=200)") hp = int(input())
while hp>200:
print("!!! INVALID !!! try again")
hp = int(input())
print("Provide positions to visit : max is 200")
requests = []
for i in range(n): req = int(input()) requests.append(req)
print(requests)
#calling the functions
print(" ********** FCFS *********")
print("Avg seek time for fcfs was ", FCFS(hp,requests))
print(" ********** SSTF *********")
print("Avg seek time for sstf was ", SSTF(hp,requests))
print(" ********** SCAN *********")
print("Avg seek time for scan was ", SCAN(hp,requests))
print(" ********** C-SCAN *********")
print("Avg seek time for C-scan was ",
C_SCAN(hp,requests))
print(" ********** LOOK *********")
print("Avg seek time for look was ",
LOOK(hp,requests))
print(" ********** C-LOOK *********")
print("Avg seek time for C-look was ",
C_LOOK(hp,requests))
print(" ********** Thanks *********")
lO M oA R cP S D| 2 81 1 40 20

21CSC202J-OPERATING SYSTEMS LAB

Output :
Result :

Successfully implemented various types of Disk Scheduling

Algorithms.

21CSC202J-OPERATING SYSTEMS LAB


EX No 14 Sequential and Indexed File Allocation
O M oA R cP S D| 2 81 1 40 20

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.

Sequential File Allocation


Algorithm :
Step 1: Start the program.
Step 2: Get the number of files.
Step 3: Get the memory requirement of each file.
Step 4: Allocate the required locations to each in sequential order a).
Randomly select a location from available location s1= random(100);
a) Check whether the required locations are free from the selected
location.
if(b[s1].flag==0){
for
(j=s1;j<s1+p[i];j++){
if((b[j].flag)==0)count++;
}
if(count==p[i]) break;
}
b) Allocate and set flag=1 to the allocated locations. for(s=s1;s<(s1+p[i]);s+
+) {
k[i][j]=s; j=j+1; b[s].bno=s;
b[s].flag=1;
}
Step 5: Print the results file no, length, Blocks allocated.
Step 6: Stop the program

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

int AllocateBlocks(int Size) {

int i = 0, count = 0, inList = 0, nextBlock = 0;


int allocStartBlock = TOTAL_DISK_INODES;
int allocEndBlock = TOTAL_DISK_BLOCKS - 1;
// check whether sufficient free blocks are available
for (i = 0; i < (TOTAL_DISK_BLOCKS -
TOTAL_DISK_INODES); i++) if (blockStatus[i] ==
0)
count++;
if (count < Size)
return 1; // not enough free blocks
count = 0;
while (count < Size) {
nextBlock = (rand() % (allocEndBlock - allocStartBlock + 1)) + allocStartBlock;
for (i = nextBlock; i < (nextBlock + Size); i++) {
if (blockStatus[i] == 0)
count = count + 1;
else { count =
0; break;
}
}
}
blockStart = nextBlock;
for (int i = 0; i < Size; i++) {
blockStatus[blockStart + i] = 1;
}
if (count == Size)
return nextBlock; // success
else
return 1; // not successful
}
void main() {
int i = 0, j = 0, numFiles = 0, nextBlock = 0, ret = 1,
totalFileSize = 0; char s[20];
//-- -
char *header[] = {"FILE_fileName", "FILE_SIZE", "BLOCKS_OCCUPIED"};
printf("File allocation method: SEQUENTIAL\n");
printf("Total blocks: %d\n", TOTAL_DISK_BLOCKS);
printf("File allocation start at block: %d\n",
TOTAL_DISK_INODES); printf("File allocation end at
block: %d\n", TOTAL_DISK_BLOCKS - 1); printf("Size (kB)
of each block: 1\n\n");
printf("Enter no of files: ");
21CSC202J-OPERATING SYSTEMS LAB

scanf("%d", &numFiles); //numFiles = 3; for (i = 0; i < numFiles; i++) { //-- -


lO M oA R cP S D| 2 81 1 40 20

printf("\nEnter the name of file #%d: ", i+1);


scanf("%s", fileTable[i].fileName); printf("Enter
the size (kB) of file #%d: ", i+1); scanf("%d",
&fileTable[i].fileSize);
//strcpy(fileTable[i].fileName, "testfile");
srand(1234);
ret = AllocateBlocks(fileTable[i].fileSize);
//-- -
if (ret == 1) {
exit(0);
} else {
fileTable[i].startBlock = ret;
}
}
//-- -
printf("\n%*s %*s %*s\n", -MAX, header[0], -MAX, header[1], MAX,
header[2]); //Seed the pseudo-random number generator used by
rand() with the value seed srand(1234);
//-- -
for (j = 0; j < numFiles; j++) {
printf("\n%*s %*d ", -MAX, fileTable[j].fileName, -MAX,
fileTable[j].fileSize); for(int k=0;k<fileTable[j].fileSize;k++)
{ printf("%d%s", fileTable[j].startBlock+k, (k ==
fileTable[j].fileSize 1) ? "" : "-"); }
}
printf("\nFile allocation completed. Exiting.\n");
}

Output :

lO M oA R cP S D| 2 81 1 40 20

Indexed File Allocation :


ALGORITHM:

You might also like