You are on page 1of 11

ASSIGNMENT-2 REPORT

OPERATING SYSTEMS – 2
AMITANSHU SAHOO | ME18BTECH11050

FUNCTION AND STRUCTURE DESCRIPTION


EDF
• Struct PCB: - This structure is analogous to the Process Control Block in the operating
systems.

This structure contains all the information related to a certain process in the system.
The following are some of the information that it contains in its variables.

p – Period of the process


t – CPU Burst time of the process.
k – Number of times the process repeats.
next_start_point – It is the start time of the next period of the process.
next_deadline – It is the time of the next upcoming deadline of the process.
last_finish_time - It is the time at which the process last finished processing.
waiting_time - It stores the sum of the waiting times of each repetition of the process
from the point of time at which the process becomes runnable.
time_left – It is the time left to complete a certain CPU Burst.
deadline_miss – It is counter variable that stores the number of times a process misses a
deadline.
iterations – It is a counter variable which keeps account of the number times a process
has executed.

• Struct compare_deadline – It is a special struct used to perform operator overloading to


use STL Library to use structure priority queue. It contains a function to conduct
comparison over the deadline of the processes while admitting them into the priority
queue. The function breaks ties in case of same deadline by using the process ID of the
process.

• Struct compare_processID - It is a special struct used to perform operator overloading to


use STL Library to use structure priority queue. It contains a function to conduct
comparison over the process ID of the processes while admitting them into the priority
queue.
RMS
• Struct PCB: - This structure is analogous to the Process Control Block in the operating
systems.

This structure contains all the information related to a certain process in the system.
The following are some of the information that it contains in its variables. It is the same
structure as used in the EDF algorithm.

• Struct compare_period – It is a special struct used to perform operator overloading to


use STL Library to use structure priority queue. It contains a function to conduct
comparison over the deadline of the processes while admitting them into the priority
queue. The function breaks ties in case of same deadline by using the process ID of the
process.

• Struct compare_processID - It is a special struct used to perform operator overloading to


use STL Library to use structure priority queue. It contains a function to conduct
comparison over the process ID of the processes while admitting them into the priority
queue.

PROGRAM FLOW
EDF
The most important function in this program is the EDF_Scheduler as it performs all the
function from reading from the file, scheduling the processes, and writing back the
results to the output file.
We use three priority queues in the program to carry out the scheduling function. All of
them use the PCB structure to store information: -
1. queue - This is the main priority queue which stores all the processes according
to their deadlines.
2. temp_queue - This queue is used to temporarily hold some processes during
situations as described below. It also stores the processes according to the
deadline of the process.
3. retired_process – The processes are pushed into this queue once all their cycles
are over. The queue is used to retrieve information about the processes at the
end of the function.
At the beginning of the function all the PCBs for the processes are initialized and are
pushed to the “queue” priority queue. The preliminary information of all the processes
is printed to the output file.
A while loop runs next until the “queue” becomes empty i.e., that all the process retires
and are pushed to the retired_process queue.
FIRST CASE
Inside the while loop we first take the top element of the “queue” and see if the
associated process is available to run at the global_time (Present Time) or not. If the
process is runnable at the time, we see if the process is starting new or if it is a
preempted process. We check this by checking the time_left variable in the PCB for the
process. If the time_left is equal to 0 then the process is starting new else, it is a
preempted process which needs to be continued.
When a process is starting new, we first check if the sum of the present time and the
CPU burst time exceeds the deadline of the process. If the process exceeds the deadline
then we skip the process and the waiting time of the process for that iteration becomes
equal to the period of the process.
If the time_left variable is not equal to zero, then the preempted process is run until it
finishes.
Pseudocode for the first process.
If first process is runnable {

If the process is starting new (check time left variable) {

If the process cannot execute within the deadline {

Skip the process;

Update the waiting time for the cycle as the period of the process;

Else {

Run the process;

Else the process is preempted {

Run the prempted process;

Update the PCB;

Push current information to log file;

SECOND CASE
The second case i.e., the process having the top priority is not available to run at the
current point of time. In such case we first find the PCB of the process which is now
available to run. We search this process by the deadline. We iterate over the PCBs in the
“queue” until we find the process whose “next_start_point” is smaller than the global
time.
To conduct the search, we pop the processes from the “queue” and push them into the
“temp_queue”. In such a way “temp_queue” has all the process PCBs whose deadline is
smaller than the deadline of the process that is available to run at the current point of
time. Hence the next process which can run after this selected process will be from the
“temp_queue”.
I named the first process as “runnable_1” and the latter process as “runnable_2”. We
need to know the information about “runnable_2” because only then we would know if
the process “runnable_1” will be preempted or carry out until the end. This was not the
situation in the first case i.e. the process having the top priority is available to run. It is
because there was no process before it and being the process with earliest deadline it
does not need to be preempted.
In this second case also we have two cases where the process “runnable_1” is starting
new or is a preempted process. A new process can have both cases of getting completed
or preempted. Same is the case with the already preempted “runnable_1” process. This
leads to two sub-if statement dealing with the above cases.
A small pseudocode showing the process:-
In the above cases if the process is starting, we check if the sum of CPU-Burst time and
the current time exceeds the deadline of the process. If it does the process is skipped
and the waiting time of that cycle becomes equal to the waiting time of the period of the
process.
After the second case gets executed the “queue” is updated with the changes and also all
the processes are brought to the “queue”. From the temp_queue. If a certain process has
completed all its cycles, then it is sent to the retired_process queue.
This concludes the while loop. After the while loop is completed the statistics output file
is opened and the waiting time, number of deadlines missed for each process are
calculated along with the average deadline for all the processes. The information is
written to the statistics file. This concludes the program.
Pseudocode for the second case and the statistic file update.
If first process is not runnable {

Find the process "runnable_1" that is runnable at that point of time;

Find the process "runnable_2" from the "temp_queue" that will be run by the system after the process "runnable_1”;

If the two processes mentioned above have same deadline and "runnable_1" has smaller process ID than "runnable_2"{

carry out the steps in the first part;

Else {

If the "runnable_1" process is starting new {

If the sum of the CPU Burst time and global time exceed the deadline {

skip the process;

update the waiting time for that cycle to be equal to the period of the process;

Else {

If the complete CPU Burst time of process will exceed the time point when "runnable_2"
becomes available to run {

Run the process "runnable_1" and preempt it when "runnable_2" becomes available to
run as it has smaller deadline;

Else {

Run "runnable_2" until it finishes;

Else {

If the complete CPU Burst time of process will exceed the time point when "runnable_2" becomes available
to run {

Resume the process "runnable_1" and preempt it when "runnable_2" becomes available to run as
it has smaller deadline;

Else {

Resume and run "runnable_2" until it finishes;

update the PCBs in the "queue" priority queue;

empty the temp_queue;

If a process completes all its cycles, send it to retired_process queue;

}
RMS
The program flow for RMS is same as the program flow for the EDF algorithm with
some changes.
1. The priority queue is decided based on the period rather than the deadline of the
process.
2. All the comparisons are made with respect to the starting of the period rather
than the deadline of the process.
3. The deadline miss for a process is checked for not only at the starting of the
process but also when a preempted process is continued. The moment the
program finds that the process will miss its deadline it is stopped (It might also
be a preempted process which is half-executed). The waiting time in such a case
is updated to be the period of the process.

The philosophy behind skipping a process in the case of EDF and RMS are a bit
different. In EDF, since the algorithm is deadline dependent, we can know if the
process will miss the deadline right at the start of the execution of the process.
But this is not the case with RMS. In RMS, the process may get preempted at
anytime of the period by a process having a shorter period. Hence, we cannot
predict at the starting if the process will get preempted or not.

Pseudocode for the RMS Algorithm for both first and second part is as follows: -
If first process is runnable {

If the process is starting new (check time left variable) {

If the process cannot execute within the deadline {

Skip the process;

Update the waiting time for the cycle as the period of the process;

Else {

Run the process;

Else the process is preempted {

If the process cannot execute within the deadline {

Skip the process;

Update the waiting time for the cycle as the period of the process;

Else {

Run the prempted process;

}
Update the PCB;

Push current information to log file;

Else {

Find the process "runnable_1" that is runnable at that point of time;

Find the process "runnable_2" from the "temp_queue" that will be run by the system after the process "runnable_1”;

If the two processes mentioned above have same deadline and "runnable_1" has smaller process ID than "runnable_2"{

carry out the steps in the first part (First process is runnable);

Else {

If the "runnable_1" process is starting new {

If the sum of the CPU Burst time and global time exceed the deadline {

skip the process;

update the waiting time for that cycle to be equal to the period of the process;

Else {

If the complete CPU Burst time of process will exceed the time point when "runnable_2"
becomes available to run {

Run the process "runnable_1" and preempt it when "runnable_2" becomes available to
run as it has smaller deadline;

Else {

Run "runnable_2" until it finishes;

Else {

If the sum of the CPU Burst time and global time exceed the deadline {

skip the process;

update the waiting time for that cycle to be equal to the period of the process;

Else {

If the complete CPU Burst time of process will exceed the time point when "runnable_2"
becomes available to run {

Resume the process "runnable_1" and preempt it when "runnable_2" becomes


available to run as it has smaller deadline;

Else {

Resume and run "runnable_2" until it finishes;

}
}

update the PCBs in the "queue" priority queue;

empty the temp_queue;

If a process completes all its cycles, send it to retired_process queue;

}
GRAPHICAL ANALYSIS

The above picture shows the data used in plotting the two graphs. For running 20
processes, the first 2 rows were used, for running 30 processes the first 4 rows were
used and so on.
DEADLINE MISSED VS NUMBER OF PROCESSES
The above graph shows the number of processes that missed the deadlines Vs total
number of processes. As could be expected the number of deadlines missed by the EDF
Algorithm is less than the number of deadlines missed by the RMS Algorithm. The
reason behind this is that the RMS algorithms are more prone to get preempted than the
EDF algorithm because it is period based.
The RMS algorithm also shows some degree of irregular behavior (Although this is
inferred for a single data table but upon checking other data tables I also found the same
to be true). The plot is not a linear function of the increase in the number of process.
The EDF Algorithm on the other hand shows a smoother curve. The changes in the
number of processes which do not meet the deadline becomes smaller for higher
number of processes. There is high difference in the number during the starting of the
graph.
The number of deadlines missed by the EDF algorithm stays 0 until 40-50 processes in
many cases whereas it is less for the RMS.

AVERAGE WAITING TIME VS NUMBER OF PROCESSES


The above graph shows the Average waiting time Vs the number of processes. The
above graphs shows that there is no marked difference in the average waiting time for
both the graphs.
The graphs show greater increase in the waiting time for smaller number of processes
and becomes more and more flat as the number of processes increases. The RMS
algorithm performs marginally better than the EDF algorithm at higher number of
processes. However, this observation is more process dependent and, in some cases,
EDF algorithm is seen to perform better than the RMS algorithm for similar number of
processes.
Also, in this case the graph for RMS is more erratic in behavior than the EDF algorithm.

You might also like