KEMBAR78
Final Os File | PDF | Operating System | Scheduling (Computing)
0% found this document useful (0 votes)
4 views47 pages

Final Os File

The document is a lab file for a B.Tech course in Computer Science & Engineering at Galgotias College, detailing practical experiments related to operating systems. It covers hardware and software requirements for various operating systems including UNIX, Linux, Windows, and Android, as well as practical exercises on UNIX system calls, CPU scheduling policies, file storage allocation techniques, and memory management. Each section includes aims, theoretical background, code implementations, and conclusions from the experiments.

Uploaded by

Pallavi Pandey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views47 pages

Final Os File

The document is a lab file for a B.Tech course in Computer Science & Engineering at Galgotias College, detailing practical experiments related to operating systems. It covers hardware and software requirements for various operating systems including UNIX, Linux, Windows, and Android, as well as practical exercises on UNIX system calls, CPU scheduling policies, file storage allocation techniques, and memory management. Each section includes aims, theoretical background, code implementations, and conclusions from the experiments.

Uploaded by

Pallavi Pandey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

Galgotias College of Engineering & Technology

Affiliated to Dr. A.P.J. Abdul Kalam Technical University

B.Tech. in Computer Science & Engineering (AIML)

LAB FILE
Operating System (BCS-451)
(Even Semester, 2024-25)

Student Name : Pallavi Pandey Roll No. : 2400971539009


Faculty Name : Mrs. Jyoti Nagpal Section : CSE-AIML-B
Year : Second Semester : 4th
PRACTICAL-1

AIM: Study of hardware and software requirements of different operating


systems (UNIX, LINUX, WINDOWS XP, WINDOWS 7/8).

Introduction
An Operating System (OS) is essential software that manages the hardware and software
resources of a computer or mobile device. It acts as an interface between the user and the
hardware. Each operating system has specific requirements to run properly, including
minimum hardware specifications and necessary software components. This project discusses
the hardware and software requirements of four widely used operating systems: Linux,
UNIX, Windows, and Android.

UNIX
UNIX is a powerful, multi-user operating system commonly used in servers and large
enterprise environments. Unlike Linux, most UNIX versions are not open source.

Hardware Requirements
 Processor: 1 GHz (minimum)
 Memory: 1 GB (minimum)
 Hard Disk Space: 10 GB free space (minimum)
 Input/Output Devices: Keyboard and Mouse

Software Requirements
 UNIX Kernel
 UNIX Shell
 U li es: Text editors, file managers, network tools

Commands
 date→ Displays current date and me

 cal → Displays calendar


 echo PALLAVI PANDEY→ Outputs: Pallavi Pandey

 mkdir → Create directory (No Output)

 pwd→ To print the complete path of the current working directory.

 cd → Change directory

 cat → Concatenate and display file contents

 ls → List directory contents

 tty → It will display the terminal name.

 cp → To copy the contents from source to destination file .so that both contents are
same.

 who → It is used to display who are the users connected to our computer currently.

 whoami → Display the details of the current working directory.


 tput setab→ is used to set the background color of the terminal text.

 rm→ To delete a file(No output)

 sort→ To sort the contents.

 wc→ To list the content count of no of lines , words, characters .

 grep→ It is used to search and print the specified patterns from the file.

 tr→ It is used to translate one set of characters from the standard inputs to another.

 head→ It is used to display the top ten lines of file.

 tail→ This command is used to display the last ten lines of file.
 rmdir→ To remove a directory in the current directory & not the current directory
itself.( no output)

 list→ It is used to list all the contents in the current working directory.

 move→ To completely move the contents from source file to destination file
and to remove the source file.

 clear→ It is used to clear the screen. (No output)

LINUX

Linux is a free, open-source operating system used in many fields, such as web servers,
desktops, and embedded systems. It is popular for its stability, security, and customization
options.

Hardware Requirements
 Processor: 1 GHz or faster
 Memory: 1 GB (minimum)
 Hard Disk Space: 20 GB free space (minimum)
 Graphics Card: 1024x768 or higher
 Input/Output Devices: Keyboard and Mouse

Software Requirements
 Linux Kernel
 Desktop Environment: GNOME, KDE, Xfce, LXDE, etc.
 Compiler: GCC
 Text Editors: Vim, Nano, Emacs, etc.
Windows
Windows is one of the most widely used operating systems, especially on
personal computers. Developed by Microsoft, it offers a user-friendly interface
and supports a wide range of applications.

Hardware Requirements
 Processor: 1 GHz or faster
 Memory: 1 GB for 32-bit or 2 GB for 64-bit
 Hard Disk Space: 16 GB for 32-bit OS or 20 GB for 64-bit OS
 Graphics Card: DirectX 9 or later with WDDM 1.0 driver

Software Requirements
 Internet Connec on
 Microso Account

Android
Android is the most popular mobile operating system in the world. It is based on
the Linux kernel and is primarily used in smartphones and tablets.

Hardware Requirements
 Runs on ARM or x86 processors
 Minimum: 512 MB RAM and 8 GB storage
 Most modern phones have at least 2 GB RAM and 32 GB storage
 Requires touchscreen support, sensors, and some mes camera or GPS
modules

Software Requirements
 Uses Android Run me (ART) to run applica ons
 Apps are developed using Java or Kotlin
 Common file systems include ext4 or F2FS
 Apps are distributed in APK format and installed via Google Play Store
 Boot process involves Fast boot or OEM-specific bootloaders

Comparison Table
Conclusion
Different operating systems have different roles and requirements. Linux and UNIX are best
suited for professional or server environments. Windows is designed for general-purpose use
on personal and office computers, while Android is specifically built for mobile devices.
Understanding their basic hardware and software needs helps us choose the right OS for our
devices and use cases.
PRACTICAL-2

AIM: Execute various UNIX system calls for:


 Process management
 File management
 Input/output Systems calls

Theory
This experiment explores the basic UNIX system calls for managing processes, files, and
input/output operations. These calls are essential for performing low-level operations in
UNIX-based operating systems.

Process Management:
This involves system calls that handle process crea on, execu on, and termina on. Common
calls include fork(), exec(), wait(), and getpid(). These allow mul tasking and process
synchroniza on.
Code:
File Management:
In UNIX, everything is treated as a file. File management system calls like open(), read(),
write(), close(), and unlink() allow programs to create, access, and manage files.
Code:

System Call:
These provide mechanisms for programs to perform input and output opera ons. Calls like
read(), write(), and lseek() are used for reading from and wri ng to files or devices.
Code:
Conclusion
Successfully executed UNIX system calls related to process management, file management,
and I/O operations.
Process creation, execution, and synchronization were demonstrated using fork(), exec(), and
wait().
File handling operations like open(), read(), write(), and close() were performed effectively.
Additional calls such as execlp(), unlink(), and fsync() were also implemented successfully.
The experiment provided a clear understanding of basic UNIX system call functionalities.
PRACTICAL-3

AIM: To implement CPU Scheduling Policies: i. Shortest Job First (SJF) ii.
Priority Scheduling iii. First Come First Serve (FCFS) iv. Multi-Level Queue
Scheduling.

Theory
CPU scheduling is the process of selecting a process from the ready queue and allocating the
CPU to it. Efficient scheduling increases CPU utilization and system responsiveness.

i. Shortest Job First(SJF)

The process with the smallest execution time is selected next. It can be preemptive or non-
preemptive. SJF offers a minimum average waiting time but requires knowledge of future
burst times.

Code:
ii. Priority Scheduling
Each process is assigned a priority. The CPU is allocated to the process with the highest
priority. It can be preemptive or non-preemptive. Lower-priority processes may suffer from
starvation if not handled properly.

Code:
iii. First Come First Serve(FCFS)

The simplest scheduling algorithm, where the process that arrives first gets executed first. It
is non-preemptive and easy to implement, but can cause long waiting times.

Code:
iv. Multi-Level Queue Scheduling
Processes are divided into groups (queues) based on properties like priority or memory
requirement. Each queue may have its own scheduling algorithm. This approach allows
separation between system and user processes, improving efficiency.

Code:

Conclusion
Successfully implemented and simulated the CPU scheduling algorithms:
First Come First Serve (FCFS), Shortest Job First (SJF), Priority Scheduling & Multi-Level
Queue Scheduling
PRACTICAL-4

AIM: Implement file storage allocation technique:(i) Contiguous (using array)


(ii) Linked –list (using linked-list) (iii)Indirect allocation (indexing).

Theory
File allocation techniques are methods used by operating systems to manage how files are
stored on disk blocks. When you save a file, it usually doesn't occupy just one block; it may
span multiple blocks depending on its size. These techniques define how those blocks are
assigned to a file so the system can access the file data efficiently.

i. Contiguous (using array)


Contiguous allocation is a file storage technique in which all blocks of a file are stored
together in a continuous (unbroken) block of memory or disk space.

Code:
Output:

ii. Linked –list (using linked-list)


This method solves all problems of contiguous allocation. In linked allocation scheme
each file is a linked list of disk blocks scattered on the disk. The first word of each block
is used as a pointer to the next one and the rest of block is used for data.

Code:
Output:

iii. Indirect allocation (indexing)


Indexed allocation method eliminates the disadvantages of linked list allocation by bringing
all the pointers together into one location, called the index block.

Code:

Output:
PRACTICAL-5

AIM: Implementation of contiguous allocation techniques: (i)Worst-Fit,


(ii)Best- Fit, (iii)First- Fit

Theory
Contiguous allocation is one of the simplest file storage methods used by an operating system
to manage files on a disk. In this technique, each file is stored in one continuous block of disk
memory.

i. Worst Fit
Allocates the largest available memory block, leaving the biggest possible leftover space.
Code:
Output:

ii. Best Fit


Allocates the smallest available memory block that is just large enough to fit the process,
minimizing wasted space.

Code:
Output:

iii. First Fit


Allocates the first available memory block that is large enough to hold the process.

Code:
Output:
PRACTICAL-6

AIM: Calculation of external and internal fragmentation, free space list of blocks from
system, List process file from the system.

Description:
IMPLEMENTATION DETAILS:
INPUT/s:
(i) Free space list of blocks from system (as in program 4).
(ii) List processes and files from the system (as in program 4).

STEPS TO PERFORM:
(i) Completing experiment contiguous allocation techniques, we end up getting list of allotted files,
remaining part of allotted block and blocks which cannot be allotted
(ii) After implementing each allocation algorithm, list the amount of free space blocks left out after
performing allocation.
(iii) When a block which is not at all allocated to any process or file, it adds to external fragmentation.
(iv) When a file or process is allocated the free block and still some part of it is left unused, we count
such unused portion into internal fragmentation.

OUTPUT/s:
Processes and files allocated to free blocks. From the list of unused blocks, we determine the count
of total internal and external fragmentation.
PRACTICAL-7
AIM: Implementation of Compaction for the continually changing memory layout and
calculate total movement of data.

Description:
Compaction is a process in which the free space is collected in a large memory chunk to make
some space available for processes.
In memory management, swapping creates multiple fragments in the memory because of the
processes moving in and out.
Compaction refers to combining all the empty spaces together and processes.
Compaction helps to solve the problem of fragmentation, but it requires too much of CPU time.
It moves all the occupied areas of store to one end and leaves one large free space for incoming
jobs, instead of numerous small ones.
In compaction, the system also maintains relocation information and it must be performed on
each new allocation of job to the memory or completion of job from memory.

ALGORITHM
Compaction is a method to overcome the external fragmentation problem.
All free blocks are brought together as one large block of free space.
Compaction requires dynamic relocation. Certainly, compaction has a cost and selection of an
optimal compaction strategy is difficult.
One method for compaction is swapping out those processes that are to be moved within the
memory, and swapping them into different memory locations.

Solution:
#include<stdio.h>
#include<conio.h>
void create(int,int);
void del(int);
void compaction();
void display();
int fname[10],fsize[10],fstart[10],freest[10],freesize[10],m=0,n=0,start;
int main()
{
int name,size,ch,i;
int *ptr;
// clrscr();
ptr=(int *) malloc(sizeof(int)*100);
start=freest[0]=(int)ptr;
freesize[0]=500;
printf("\n\n");
printf(" Free start address Free Size \n\n");
for(i=0;i<=m;i++)
printf("%d %d\n",freest[i],freesize[i]);
printf("\n\n");
while(1)
{
printf("1.Create.\n");
printf("2.Delete.\n");
printf("3.Compaction.\n");
printf("4.Exit.\n");
printf("Enter your choice: ");
scanf("%d",&ch);
switch(ch)
{
case 1: printf("\nEnter the name of file: ");
scanf("%d",&name);
printf("\nEnter the size of the file: ");
scanf("%d",&size);
create(name,size);
break;
case 2:printf("\nEnter the file name which u want to delete: ");
scanf("%d",&name);
del(name);
break;
case 3:compaction();
printf("\nAfter compaction the tables will be:\n");
display();
break;
case 4:
exit(1);
default: printf("\nYou have entered a wrong choice.\n");
}
}}
void create(int name,int size)
{
int i,flag=1,j,a;

for(i=0;i<=m;i++)
if( freesize[i] >= size)
a=i,flag=0;
if(!flag)
{
for(j=0;j<n;j++);
n++;
fname[j]=name;
fsize[j]=size;
fstart[j]=freest[a];
freest[a]=freest[a]+size;
freesize[a]=freesize[a]-size;
freesize[a]-=size;
printf("\n The memory map will now be: \n\n");
display();
}
else
printf("\nNo enough space.\n");
} }
void del(int name)
{
int i,j,k,flag=1;
for(i=0;i<n;i++)
if(fname[i]==name)
break;
if(i==n)
{
flag=0;
printf("\nNo such process exists......\n");
}
else{
m++;
freest[m]=fstart[i];
freesize[m]=fsize[i];
for(k=i;k<n;k++)
{
fname[k]=fname[k+1];
fsize[k]=fsize[k+1];
fstart[k]=fstart[k+1];
}
n--;}
if(flag) {
printf("\n\n After deletion of this process the memory map will be : \n\n");
display();
} }
void compaction()
{
int i,j,size1=0,f_size=0;
if(fstart[0]!=start) {
fstart[0]=start;
for(i=1;i<n;i++)
printf("\n The memory map will now be: \n\n");
display(); }
else {
printf("\nNo enough space is available.System compaction......");
flag=1;
compaction();
display();
for(i=0;i<=m;i++)
if( freesize[i] >= size)
a=i,flag=0;
if(!flag) {
for(j=0;j<n;j++);
n++;
fname[j]=name;
fsize[j]=size;
fstart[j]=freest[a];
freest[a]+=size;
fstart[i]=fstart[i-1]+fsize[i-1];
}
else {
for(i=1;i<n;i++)
fstart[i]=fstart[i-1]+fsize[i-1];
}
f_size=freesize[0];
for(j=0;j<=m;j++)
size1+=freesize[j];
freest[0]=freest[0]-(size1-f_size);
freesize[0]=size1;
m=0;
}
void display()
{
int i;
printf("\n *** MEMORY MAP TABLE *** \n");
printf("\n\nNAME SIZE STARTING ADDRESS \n\n");
for(i=0;i<n;i++)
printf(" %d%10d%10d\n",fname[i],fsize[i],fstart[i]);
printf("\n\n");
printf("\n\n*** FREE SPACE TABLE ***\n\n");
printf("FREE START ADDRESS FREE SIZE \n\n");
for(i=0;i<=m;i++)
printf(" %d %d\n",freest[i],freesize[i]);
}

OUTPUT:
PRACTICAL-8
AIM: Implementation of Banker‟s algorithm.

Description: The banker’s algorithm is a resource allocation and deadlock avoidance


algorithm that tests for safety by simulating the allocation for predetermined maximum
possible amounts of all resources, then makes an “s-state” check to test for possible activities,
before deciding whether allocation should be allowed to continue.
Following Data structures are used to implement the Banker‟s Algorithm:
Let ‘n’ be the number of processes in the system and ‘m’ be the number of resources types.
Available:
It is a 1-d array of size ‘m’ indicating the number of available resources of each type.
Available[ j ] = k means there are ‘k’ instances of resource type Rj

Max:
It is a 2-d array of size „n*m’ that defines the maximum demand of each process in a system.
Max[ i, j ] = k means process Pi may request at most ‘k’ instances of resource type Rj.

Allocation:
It is a 2-d array of size ‘n*m’ that defines the number of resources of each type currently
allocated to each process.
Allocation[ i, j ] = k means process Pi is currently allocated ‘k’ instances of resource type Rj

Need:
It is a 2-d array of size ‘n*m’ that indicates the remaining resource need of each process.
Need [ i, j ] = k means process Pi currently need ‘k’ instances of resource type Rj for its
execution.
Need [ i, j ] = Max [ i, j ] – Allocation [ i, j ]

Allocationi specifies the resources currently allocated to process Pi and Needi specifies the
additional resources that process Pi may still request to complete its task.

Banker‟s algorithm consists of Safety algorithm and Resource request algorithm

Safety Algorithm
The algorithm for finding out whether or not a system is in a safe state can be described as
follows:
1) Let Work and Finish be vectors of length „m‟ and „n‟ respectively. Initialize:
Work = Available Finish[i] = false; for i=1, 2, 3, 4….n
2) Find an i such that both
a) Finish[i] = false
b) Needi <= Work if no such i exists goto step (4)
3) Work = Work + Allocation[i] Finish[i] = true goto step (2)
4) if Finish [i] = true for all i then the system is in a safe state
Resource-Request Algorithm
Let Requesti be the request array for process Pi. Requesti [j] = k means process Pi wants k
instances of resource type Rj. When a request for resources is made by process Pi, the following
actions are taken:
1) If Requesti <= Needi Goto step (2) ; otherwise, raise an error condition, since the process
has exceeded its maximum clAim.
2) If Requesti <= Available Goto step (3); otherwise, Pi must wait, since the resources are not
available.
3) Have the system pretend to have allocated the requested resources to process Pi by
modifying the state as follows:
Available = Available – Requesti Allocationi = Allocationi + Requesti Needi = Needi–
Requesti

Program:
#include <stdio.h>
int main()
{
int count = 0, m, n, process, temp, resource;
int allocation_table[5] = {0, 0, 0, 0, 0};
int available[5], current[5][5], maximum_clAim[5][5];
int maximum_resources[5], running[5], safe_state = 0;
printf("\nEnter The Total Number Of Processes:\t");
scanf("%d", &process);
for(m = 0; m < process; m++)
{
running[m] = 1;
count++;
}
printf("\nEnter The Total Number Of Resources To Allocate:\t");
scanf("%d", &resource);
printf("\nEnter The ClAim Vector:\t");
for(m = 0; m < resource; m++)
{
scanf("%d", &maximum_resources[m]); }
printf("\nEnter Allocated Resource Table:\n");
for(m = 0; m < process; m++)
{
for(n = 0; n < resource; n++) {
scanf("%d", &current[m][n]);
}}
printf("\nEnter The Maximum ClAim Table:\n");
for(m = 0; m < process; m++)
{
for(n = 0; n < resource; n++) {
scanf("%d", &maximum_clAim[m][n]);
} }
printf("\nThe ClAim Vector \n");
for(m = 0; m < resource; m++) {
printf("\t%d ", maximum_resources[m]); }
printf("\n The Allocated Resource Table\n");
for(m = 0; m < process; m++)
{
for(n = 0; n < resource; n++) {
printf("\t%d", current[m][n]); }
printf("\n");
}
printf("\nThe Maximum ClAim Table \n");
for(m = 0; m < process; m++)
{
for(n = 0; n < resource; n++) {
printf("\t%d", maximum_clAim[m][n]);
}
printf("\n");
}
for(m = 0; m < process; m++)
{
for(n = 0; n < resource; n++) {
allocation_table[n] = allocation_table[n] + current[m][n];
} }
printf("\nAllocated Resources \n");
for(m = 0; m < resource; m++)
{
printf("\t%d", allocation_table[m]); }
for(m = 0; m < resource; m++)
{
available[m] = maximum_resources[m] - allocation_table[m]; }
printf("\nAvailable Resources:");
for(m = 0; m < resource; m++)
{
printf("\t%d", available[m]); }
printf("\n");
while(count != 0) {
safe_state = 0;
for(m = 0; m < process; m++)
{
if(running[m]) {
temp = 1;
for(n = 0; n < resource; n++)
{
if(maximum_clAim[m][n] - current[m][n] > available[n]){
temp = 0;
break;
}}
if(temp) {
printf("\nProcess %d Is In Execution \n", m + 1);
running[m] = 0;
count--;
safe_state = 1;
for(n = 0; n < resource; n++)
{
available[n] = available[n] + current[m][n];
}
break;
}
}
}
if(!safe_state)
{
printf("\nThe Processes Are In An Unsafe State \n");
break;
}
else
{
printf("\nThe Process Is In A Safe State \n");
printf("\nAvailable Vector\n");
for(m = 0; m < resource; m++)
{
printf("\t%d", available[m]);
}
printf("\n");
}
}
return 0;
}

OUTPUT:
PRACTICAL-9
AIM: Implement the solution for Bounded Buffer (producer-consumer) problem using inter
process communication.

Description: In computing, the producer–consumer problem (also known as the bounded-


buffer problem) is a classic example of a multi-process synchronization problem. The problem
describes two processes, the producer and the consumer, which share a common, fixed-size
buffer used as a queue.
 The producer‟s job is to generate data, put it into the buffer, and start again.
 At the same time, the consumer is consuming the data (i.e. removing it from the buffer),
one piece at a time.

Problem : To make sure that the producer won’t try to add data into the buffer if it‟s full and
that the consumer won’t try to remove data from an empty buffer.

Solution : The producer is to either go to sleep or discard data if the buffer is full. The next
time the consumer removes an item from the buffer, it notifies the producer, who starts to fill
the buffer again. In the same way, the consumer can go to sleep if it finds the buffer to be
empty. The next time the producer puts data into the buffer, it wakes up the sleeping consumer.
An inadequate solution could result in a deadlock where both processes are waiting to be
awakened.
In the post Producer-Consumer solution, we have discussed above solution by using inter-
thread communication (wait(), notify(), sleep()). In this post, we will use Semaphores to
implement the same.
The below solution consists of four classes:
1. Q : the queue that you‟re trying to synchronize
2. Producer : the threaded object that is producing queue entries
3. Consumer : the threaded object that is consuming queue entries
4. PC : the driver class that creates the single Q, Producer, and Consumer.

Program:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
int buf[256];
int in = 0;
int out = 0;
sem_t full;
sem_t empty;
sem_t mutex;
int buf_size;
int counter = 0;
void *producer(void *arg)
{
int i, item, *index;
index = (int *)arg;
for (i = 0;; i++)
{
item = 1000 + i;
sem_wait(&empty);
sem_wait(&mutex);
buf[in] = item;
in = (in + 1) % (*index);
counter++;
printf("\n%d [P%d] ", item, *index);
sem_post(&mutex);
sem_post(&full);
/* if (i % 5 == 0)
sleep(1); */
}
}
void *consumer(void *arg)
{
int i, item, *index;
index = (int *)arg;
for (i = 0;;i++)
{
sem_wait(&full);
sem_wait(&mutex);
item = buf[out];
out = (out + 1) % (*index);
counter--;
printf("\n%d [C%d] ", item, *index);
sem_post(&mutex);
sem_post(&empty);
/* if (i % 5 == 0)
sleep(1); */
}
}
int main()
{
int produce, consume;
int i;
printf("\nThe Buffer Size:");
scanf("%d", &buf_size);
printf("\nThe Producer:");
scanf("%d", &produce);
printf("\nThe Consumer:");
scanf("%d", &consume);
pthread_t prod, cons;
void* exit_status;
sem_init(&full, 0, 0);
sem_init(&empty, 0, buf_size);
sem_init(&mutex, 0, 1);
for (i = 0; i < produce; i++)
{
pthread_create(&prod, NULL, producer, &i);
}
for (i = 0; i < consume; i++)
{
pthread_create(&cons, NULL, consumer, &i);
}
pthread_join(prod, &exit_status);
pthread_join(cons, &exit_status);
// pthread_exit(NULL);
return 0;
}
Output:
Producer produced item : 0
Consumer consumed item : 0
Producer produced item : 1
Consumer consumed item : 1
Producer produced item : 2
Consumer consumed item : 2
Producer produced item : 3
Consumer consumed item : 3
Producer produced item : 4
Consumer consumed item : 4
PRACTICAL-10
AIM: Implement the solutions for Readers-Writers problem using inter-process
communication technique -Semaphore.

Description: Consider a situation where we have a file shared between many people.
 If one of the people 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 as the readers-writers problem


Problem parameters:
 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

Solution when Reader has the Priority over Writer


Here priority means, no reader should wait if the share is currently opened for reading.
Three variables are used: mutex, wrt, readcnt to implement solution
1. semaphore mutex, wrt; // semaphore mutex is used to ensure mutual exclusion when
readcnt is updated i.e. when any reader enters or exit from the critical section and semaphore
wrt is used by both readers and writers
2. int readcnt; // readcnt tells the number of processes performing read in the critical section,
initially 0

Functions for semaphore :


– wait() : decrements the semaphore value.
– signal() : increments the semaphore value.
Writer process:
1. Writer requests the entry to critical section.
2. If allowed i.e. wait() gives a true value, it enters and performs the write. If not allowed, it
keeps on waiting.
3. It exits the critical section.

Program:
#include<stdio.h>
#include<conio.h>
#include<stdbool.h>
struct semaphore
{
int mutex;
int rcount;
int rwait;
bool wrt;
};
void addR(struct semaphore *s)
{
if (s->mutex == 0 && s->rcount == 0)
{
printf("\nSorry, File open in Write mode.\nNew Reader added to queue.\n");
s->rwait++;
}
Else {
printf("\nReader Process added.\n");
s->rcount++;
s->mutex--;
}
return ;
}
void addW(struct semaphore *s)
{
if(s->mutex==1)
{
s->mutex--;
s->wrt=1;
printf("\nWriter Process added.\n");
}
else if(s->wrt) printf("\nSorry, Writer already operational.\n");
else printf("\nSorry, File open in Read mode.\n");
return ;
}
void remR(struct semaphore *s)
{
if(s->rcount == 0) printf("\nNo readers to remove.\n");
else
{
printf("\nReader Removed.\n");
s->rcount--;
s->mutex++;
}
return ;
}
void remW(struct semaphore *s)
{
if(s->wrt==0) printf("\nNo Writer to Remove");
else
printf("\nWriter Removed\n");
s->mutex++;
s->wrt=0;
if(s->rwait!=0)
{
s->mutex-=s->rwait;
s->rcount=s->rwait;
s->rwait=0;
printf("%d waiting Readers Added.",s->rcount);
}}}
int main()
{
struct semaphore S1={1,0,0};
while(1)
{
//system("cls");
printf("Options :-\n1.Add Reader.\n2.Add Writer.\n3.Remove Reader.\n4.Remove
Writer.\n5.Exit.\n\n\tChoice : ");
int ch;
scanf("%d",&ch);
switch(ch)
{
case 1: addR(&S1); break;
case 2: addW(&S1); break;
case 3: remR(&S1); break;
case 4: remW(&S1); break;
case 5: printf("\n\tGoodBye!"); getch(); return 0;
default: printf("\nInvalid Entry!"); continue;
}
printf("\n\n<<<<<< Current Status >>>>>>\n\n\tMutex\t\t:\t%d\n\tActive
Readers\t:\t%d\n\tWaiting Readers\t:\t%d\n\tWriter Active\t:\t%s\n\n", S1.mutex, S1.rcount,
S1.rwait, (S1.mutex==0 && S1.rcount==0) ? "YES" : "NO");
system("pause");
}}

OUTPUT
File open in Write mode
New reader added to queue
PRACTICAL-11
AIM: (i). Example program for Implement disk scheduling algorithms:FCFS
#include<stdio.h>
int main()
{
int queue[20],n,head,i,j,k,seek=0,max,diff;
float avg;
printf("Enter the max range of disk\n");
scanf("%d",&max);
printf("Enter the size of queue request\n");
scanf("%d",&n);
printf("Enter the queue of disk positions to be read\n");
for(i=1;i<=n;i++)
scanf("%d",&queue[i]);
printf("Enter the initial head position\n");
scanf("%d",&head);
queue[0]=head;
for(j=0;j<=n-1;j++)
{
diff=abs(queue[j+1]-queue[j]);
seek+=diff;
printf("Disk head moves from %d to %d with seek
%d\n",queue[j],queue[j+1],diff);
}
printf("Total seek time is %d\n",seek);
avg=seek/(float)n;
printf("Average seek time is %f\n",avg);
return 0;}

Output (i):
Enter the max range of disk
200
Enter the size of queue request
8
Enter the queue of disk positions to be read
90 120 35 122 38 128 65 68
Enter the initial head position
50
Disk head moves from 50 to 90 with seek
Disk head moves from 90 to 120 with seek
Disk head moves from 120 to 35 with seek
Disk head moves from 35 to 122 with seek
Disk head moves from 122 to 38 with seek
Disk head moves from 38 to 128 with seek
Disk head moves from 128 to 65 with seek
Disk head moves from 65 to 68 with seek
Total seek time is 482
Average seek time is 60.250000
AIM: (ii). Example program for Implement disk scheduling algorithms: SCAN
#include<stdio.h>
int main()
{
int queue[20],n,head,i,j,k,seek=0,max,diff,temp,queue1[20],queue2[20],
temp1=0,temp2=0;
float avg;
printf("Enter the max range of disk\n");
scanf("%d",&max);
printf("Enter the initial head position\n");
scanf("%d",&head);
printf("Enter the size of queue request\n");
scanf("%d",&n);
printf("Enter the queue of disk positions to be read\n");
for(i=1;i<=n;i++)
{
scanf("%d",&temp);
if(temp>=head)
{
queue1[temp1]=temp;
temp1++;
}
else
{
queue2[temp2]=temp;
temp2++;
}
}
for(i=0;i<temp1-1;i++)
{
for(j=i+1;j<temp1;j++)
{
if(queue1[i]>queue1[j])
{
temp=queue1[i];
queue1[i]=queue1[j];
queue1[j]=temp;
}
}
}
for(i=0;i<temp2-1;i++)
{
for(j=i+1;j<temp2;j++)
{
if(queue2[i]<queue2[j])
{
temp=queue2[i];
queue2[i]=queue2[j];
queue2[j]=temp;
}
}
}
for(i=1,j=0;j<temp1;i++,j++)
queue[i]=queue1[j];
queue[i]=max;
for(i=temp1+2,j=0;j<temp2;i++,j++)
queue[i]=queue2[j];

queue[i]=0;
queue[0]=head;
for(j=0;j<=n+1;j++)
{
diff=abs(queue[j+1]-queue[j]);
seek+=diff;
printf("Disk head moves from %d to %d with seek
%d\n",queue[j],queue[j+1],diff);
}
printf("Total seek time is %d\n",seek);
avg=seek/(float)n;
printf("Average seek time is %f\n",avg);
return 0;
}

Output :
Enter the max range of disk
200
Enter the initial head position
50
Enter the size of queue request
8
Enter the queue of disk positions to be read
90 120 35 122 38 128 65 68
Disk head moves from 50 to 65 with seek 15
Disk head moves from 65 to 68 with seek 3
Disk head moves from 68 to 90 with seek 22
Disk head moves from 90 to 120 with seek 30
Disk head moves from 120 to 122 with seek 2
Disk head moves from 122 to 128 with seek 6
Disk head moves from 128 to 200 with seek 72
Disk head moves from 200 to 38 with seek 162
Disk head moves from 38 to 35 with seek 3
Disk head moves from 35 to 0 with seek 35
Total seek time is 350
Average seek time is 43.750000

AIM: (iii). Example program for Implement disk scheduling algorithms: C-SCAN
#include<stdio.h>
int main()
{
int queue[20],n,head,i,j,k,seek=0,max,diff,temp,queue1[20],queue2[20],
temp1=0,temp2=0;
float avg;
printf("Enter the max range of disk\n");
scanf("%d",&max);
printf("Enter the initial head position\n");
scanf("%d",&head);
printf("Enter the size of queue request\n");
scanf("%d",&n);
printf("Enter the queue of disk positions to be read\n");
for(i=1;i<=n;i++)
{
scanf("%d",&temp);
if(temp>=head){
queue1[temp1]=temp;
temp1++;
}
else{
queue2[temp2]=temp;
temp2++;
}}
for(i=0;i<temp1-1;i++)
{
for(j=i+1;j<temp1;j++)
{
if(queue1[i]>queue1[j])
{
temp=queue1[i];
queue1[i]=queue1[j];
queue1[j]=temp;
}
}
}
for(i=0;i<temp2-1;i++)
{
for(j=i+1;j<temp2;j++)
{
if(queue2[i]>queue2[j])
{
temp=queue2[i];
queue2[i]=queue2[j];
queue2[j]=temp;
}} }
for(i=1,j=0;j<temp1;i++,j++)
queue[i]=queue1[j];
queue[i]=max;
queue[i+1]=0;
for(i=temp1+3,j=0;j<temp2;i++,j++)
queue[i]=queue2[j];
queue[0]=head;
for(j=0;j<=n+1;j++)
{
diff=abs(queue[j+1]-queue[j]);
seek+=diff;
printf("Disk head moves from %d to %d with seek
%d\n",queue[j],queue[j+1],diff);
}
printf("Total seek time is %d\n",seek);
avg=seek/(float)n;
printf("Average seek time is %f\n",avg);
return 0;
}

Output (iii):
Enter the max range of disk
200
Enter the initial head position
50
Enter the size of queue request
8
Enter the queue of disk positions to be read
90 120 35 122 38 128 65 68
Disk head moves from 50 to 65 with seek 15
Disk head moves from 65 to 68 with seek 3
Disk head moves from 68 to 90 with seek 22
Disk head moves from 90 to 120 with seek 30
Disk head moves from 120 to 122 with seek 2
Disk head moves from 122 to 128 with seek 6
Disk head moves from 128 to 200 with seek 72
Disk head moves from 200 to 0 with seek 200
Disk head moves from 0 to 35 with seek 35
Disk head moves from 35 to 38 with seek 3

Total seek time is 388


Average seek time is 48.500000
PRACTICAL-12
AIM: (i). Example program for Implement page replacement algorithm: FIFO
#include<stdio.h>
int main()
{
int i,j,n,page[50],frameno,frame[10],move=0,flag,count=0;
float rate;
printf("Enter the number of pages\n");
scanf("%d",&n);
printf("Enter the page reference numbers\n");
for(i=0;i<n;i++)
scanf("%d",&page[i]);
printf("Enter the number of frames\n");
scanf("%d",&frameno);
for(i=0;i<frameno;i++)
frame[i]=-1;
printf("Page reference string\tFrames\n");
for(i=0;i<n;i++)
{
printf("%d\t\t\t",page[i]);
flag=0;
for(j=0;j<frameno;j++)
{
if(page[i]==frame[j])
{
flag=1;
printf("No replacement\n");
break;
}
}
if(flag==0)
{
frame[move]=page[i];
move=(move+1)%frameno;
count++;
for(j=0;j<frameno;j++)
printf("%d\t",frame[j]);
printf("\n");
}
}
rate=(float)count/(float)n;
printf("Number of page faults is %d\n",count);
printf("Fault rate is %f\n",rate);
return 0;
}

Output :
Enter the number of pages
12
Enter the page reference numbers
021640103121
Enter the number of frames
4
Page reference string Frames
0 0 -1 -1 -1
2 0 2 -1 -1
1 0 2 1 -1
6 0 2 1 6
4 4 2 1 6

0 4 0 1 6
1 No replacement
0 No replacement
3 4 0 3 6
1 4 0 3 1
2 2 0 3 1
1 No replacement
Number of page faults is 9
Fault rate is 0.750000

AIM: (ii). Example program for Implement page replacement algorithm: LRU
#include<stdio.h>
void print(int frameno,int frame[]){
int j;
for(j=0;j<frameno;j++)
printf("%d\t",frame[j]);
printf("\n");}
int main(){
int i,j,k,n,page[50],frameno,frame[10],move=0,flag,count=0,count1,repindex,
check[50]={0};
float rate;
printf("Enter the number of pages\n");
scanf("%d",&n);
printf("Enter the page reference numbers\n");
for(i=0;i<n;i++)
scanf("%d",&page[i]);
printf("Enter the number of frames\n");
scanf("%d",&frameno);
for(i=0;i<frameno;i++)
frame[i]=-1;
printf("Page reference string\tFrames\n");
for(i=0;i<n;i++){
printf("%d\t\t\t",page[i]);
flag=0;
for(j=0;j<frameno;j++) {
if(page[i]==frame[j]){
flag=1;
printf("No replacement\n");
break; }}
if(flag==0&&count<frameno) {
frame[move]=page[i];
move=(move+1)%frameno;
count++;
print(frameno,frame); }
else if(flag==0){
count1=0;
for(j=i-1;j>=0;j--) {
for(k=0;k<frameno;k++)
{
if(page[j]==frame[k]&&check[page[j]]==0){
check[page[j]]=1;
count1++;
repindex=k;
k=frameno; }}
if(count1==frameno)
break; }
frame[repindex]=page[i];
count++;
print(frameno,frame); }
for(j=0;j<50;j++)
check[j]=0; }
rate=(float)count/(float)n;
printf("Number of page faults is %d\n",count);
printf("Fault rate is %f\n",rate);
return 0;}

Output :
Enter the number of pages
12
Enter the page reference numbers
021640103121
Enter the number of frames
4
Page reference string Frames
0 0 -1 -1 -1
2 0 2 -1 -1
1 0 2 1 -1
6 0 2 1 6
4 4 2 1 6
0 4 0 1 6
1 No replacement
0 No replacement
3 4 0 1 3
1 No replacement
2 2 0 1 3
1 No replacement
Number of page faults is 8
Fault rate is 0.666667
AIM: (iii). Example program for Implement page replacement algorithm: LRU
#include<stdio.h>
void print(int frameno,int frame[])
{
int j;
for(j=0;j<frameno;j++)
printf("%d\t",frame[j]);
printf("\n");
}
int main()
{
int i,j,k,n,page[50],frameno,frame[10],move=0,flag,count=0,count1[10]={0},
repindex,leastcount;
float rate;
printf("Enter the number of pages\n");
scanf("%d",&n);
printf("Enter the page reference numbers\n");
for(i=0;i<n;i++)
scanf("%d",&page[i]);
printf("Enter the number of frames\n");
scanf("%d",&frameno);
for(i=0;i<frameno;i++)
frame[i]=-1;
printf("Page reference string\tFrames\n");
for(i=0;i<n;i++) {
printf("%d\t\t\t",page[i]);
flag=0;
for(j=0;j<frameno;j++)
{
if(page[i]==frame[j]) {
flag=1;
count1[j]++;
printf("No replacement\n");
break;
}}
if(flag==0&&count<frameno){
frame[move]=page[i];
count1[move]=1;
move=(move+1)%frameno;
count++;
print(frameno,frame);
}
else if(flag==0){
repindex=0;
leastcount=count1[0];
for(j=1;j<frameno;j++) {
if(count1[j]<leastcount){
repindex=j;
leastcount=count1[j];
}}
frame[repindex]=page[i];
count1[repindex]=1;
count++;
print(frameno,frame);
}}
rate=(float)count/(float)n;
printf("Number of page faults is %d\n",count);
printf("Fault rate is %f\n",rate);
return 0;
}

Output :
Enter the number of pages
12
Enter the page reference numbers
021640103121
Enter the number of frames
4
Page reference string Frames
0 0 -1 -1 -1
2 0 2 -1 -1
1 0 2 1 -1
6 0 2 1 6
4 4 2 1 6
0 0 2 1 6
1 No replacement
0 No replacement
3 0 3 1 6
1 No replacement
2 0 2 1 6
1 No replacement
Number of page faults is 8
Fault rate is 0.666667

You might also like