CSC 213, Fall 2008
: Schedule : Lab 5
Lab 5: Scheduling Algorithms
The scheduling of processes within a computer depends upon three
In this lab, you will compare average wait time and system throughput
for several scheduling algorithms.
whether a process is allowed to run to completion once it is
started (i.e., whether scheduling is preemptive or nonpreemptive);
the specific algorithm used to determine the next job to be
the time slice given to a process, if
preemptive scheduling is used.
In this lab, you will
Gain first-hand experience implementing several scheduling
Apply the event-driven simulation approach to the problem of
modeling the behavior of a system over time.
Obtain comparative data on throughput and average waiting time for
different scheduling algorithms and varying scheduler
Get more experience with list structures in C.
Lab 7.1 (Nutt, p. 283-289) provides background on event-driven
- Example scheduling algorithm and simulation program:
defines the interface and data structures for a generic scheduling
which implements the First-Come First-Served scheduling algorithm,
according to the scheduler.h interface above.
, which implements a framework for simulating scheduling
algorithms. It can be linked with any object file that
implements the methods in schedule.h
which gives an example of how to compile and link the
simulator, with optional #defined parameters specified.
Collaboration: You will complete this lab in teams of 1 to 3
of your choice. You may, as always, consult with your classmates
on issues of design and debugging.
Overview of Starter Code
This header declares some structure types and functions specific to job scheduling:
int jobQueueIsEmpty( void ) returns true or false, according
to whether any jobs are waiting in the ready state.
void initializeJobQueue( void ) initializes the job
queue with no jobs currently pending.
void insertJob( struct Event* job ) adds the
specified job to the job queue.
struct Event* selectJob( void ) selects the next
job to run from the job queue, removes the job from the queue, and
struct jobQueue contains pointers to two
jobQueueNodes for a linked list that can form a jobQueue for
any scheduling algorithm.
This file contains implementations of the functions above for the FCFS
scheduling algorithm. Other scheduling algorithms will also need their
own implementations of these functions. If you wish, you may
scheduler_fcfs.c as a template for implementing the
Shortest Job Next (SJN) and Priority scheduling algorithms according
to the scheduler.h interface.
This program incorporates a scheduling algorithm into an
The program contains three debugging flags that can provide on-going
information as the simulation
Events are stored in the
eventList structure, ordered by their start time.
- The program handles three types of events:
When a job enters the system, it creates
registerJob event that enters the job into the
system's data structure for ready processes.
A scheduler event triggers the
scheduler. If jobs
are pending, the scheduler event retrieves the next job using
selectJob procedure and runs the job. If no
jobs are pending, time is advanced until the next event will
When a process is scheduled, a
is triggered. This adds any required scheduler overhead to the
clock. If processes run without preemption, then the process is
run to completion. If preemption is allowed, the process runs
for its time slice or until it is completed, whichever is
sooner. When the process stops, a new scheduler event is
registerJob events, the program reads a
sequence of jobs from a file for use in the simulation. Each job
arrival generates an event, which is placed in
TIME_QUANTUM is 0 for non-preemptive
scheduling or the size of the time slice for preemptive
scheduling. (Defaults to 0.)
SCHEDULER_OVERHEAD specifies the amount
of simulation time consumed by the scheduler each time it is
called. (Defaults to 0.35.)
After initialization, the main loop removes an event from
eventList and executes it. The scheduler is
treated as an event that is executed at the beginning of the
simulation and after each job or time slice ends.
Statistics on jobs started and waiting times are updated whenever
a process starts.
Statistics on jobs completed and processing times are updated
whenever a process finishes.
Any combination of these flags can be specified at compile time. See
the example Makefile.
Similarly, you can override the values of
PRINT_INPUT causes the job specifications to
be printed as they are read from JOB_FILE_NAME.
PRINT_EVENT_LIST causes the event list to be
printed each time through the main event loop.
PRINT_STATS causes the accumulated
job statistics to be printed each time through the main event
TIME_QUANTUM at compile time.
Non-preemptive scheduling algorithms
Run the existing program to get average waiting times and
throughputs for the FCFS scheduling algorithm, using values of
0.0, 0.01, 0.02, 0.03, and 0.04 for
SCHEDULER_OVERHEAD. (Record your measurements in
a text file or a spreadsheet.)
Implement the SJN scheduling algorithm, using
the scheduler.h interface described above.
Compile your own SJN scheduler and link it with
Run the simulation with SJN for the same cases as in step 1.
Compare the average waiting times and throughputs for FCFS and
SJN. Does this information suggest any conclusions regarding
the relative effectiveness of FCFS and SJN?
Part B: Preemptive scheduling algorithms
A simple Round-Robin (RR) scheduling algorithm can be obtained by
using the FCFS scheduler you are given, but changing
processJob event handler
scheduler_simulation.c as indicated
/* YOUR CODE HERE */. If the
TIME_QUANTUM is positive, then a job is
allowed to run continuously only for that time slice. If the job
will not finish within the time slice, then the time remaining for
the job is reduced by the time slice, and the scheduler is invoked
Run the RR scheduling simulation for the same values
SCHEDULER_OVERHEAD you did in step A.1, with the
time quanta being 0.05, 0.1, 0.15, and 0.2. (Record your
measurements in a text file or a spreadsheet.)
Implement a multi-queue priority algorithm, using
the scheduler.h interface described above. Assume
priorities are from 1 (most important) through 10 (not very
important). Vary the time slice allocated to a job according
to its priority:
time_quantum = TIME_QUANTUM / 2^(priority-1)
Again, run the resulting priority algorithm for the same values
SCHEDULER_OVERHEAD given in step A.1 and the same
time quanta specified in step B.2.
Compare the average waiting times and throughputs for the
non-preemptive and preemptive algorithms you obtained in your
simulations. Can you draw any conclusions regarding the
relative effectiveness of these
Work to be Turned In
This lab is due Tuesday 10/7.
A program from step A.2 implementing the SJN algorithm.
The statistics you measured for steps A.1 and A.4.
Your answer to the question in step A.5.
Your modified version of
step B.1 implementing the RR algorithm.
A program from step B.3 implementing the multi-queue priority
The statistics you measured for steps B.2 and B.4.
Your answer to the question in step B.5.
As always, for the programs in steps A.2, B.1, and B.3, please follow
the instructions for submitting
Note that the exam is Friday 10/3. While the lab has been
"partitioned," it is not due in its entirety until Tuesday 10/7 so
that you have ample time to study. According to syllabus, the exam
carries three times more weight than any given lab.
Created June 24, 2008
CSC 213, Fall 2006 : Lab 5 : Scheduling Algorithms
With thanks to Janet Davis and Henry Walker