CS 537
Programming Assignment III
Simulator Details

Detailed Overview


The simulation consists primarily of jobs, devices, and schedulers. The jobs arrive at the system from the trace file and are scheduled to use the system devices (the CPU and the disk). The amount of computing a job wants to do before performing disk I/O or finishing execution is called a burst. The program cycles through waiting for devices to interrupt and then handling those interrupts -- which could entail removing a job from a device and scheduling it with another device or discarding a job that has finished. In the picture below, the Main Loop waits for a device to interrupt. When it does, the Main Loop removes the job from that device and either reschedules it with the same device (as in the case of a clock interrupt), or it removes the current job from the device and enqueues it with another.


A Job object represents a customer of services. It records the job's current state and maintains statistics about its lifetime. One Job is created from each line of the input trace file, and a Job object spends its lifetime being passed between Schedulers and Devices.

The resources required by a Job are characterized by an amount CPU time needed (all times are in milliseconds) and the number of I/O operations needed (each representing one disk transfer of Sim.BLOCKSIZE bytes of data). The CPU time is generally distributed as evenly as possible into uniform bursts between I/O operations (unless the job does no I/O at all); however, occasionally a little randomness is injected into the system, and the CPU burst is less than or greater than expected.


A Device object represents a resource such as the Disk, the Clock, or the CPU. It can be running or stopped; however once started, it will ``interrupt'' at some time in the future. The Device object keeps track of the current device state as well as at what time the next interrupt will occur. The method Sim.mainLoop() monitors devices closely for their interrupts, and when one occurs, Sim.mainLoop() advances its current time to the interrupt time, stops the device, and does what an ``interrupt handler'' for the device would do.


Schedulers exist for the CPU and the Disk and schedule Jobs seeking service from a device. They maintain a queue of waiting jobs and determine which of those jobs will be the next to access the device. (Job objects contain pointers to other Job objects -- these can be used to create the Job lists.) The default CPU scheduler uses a Round-Robin (RR) algorithm to determine the next job to run; the Disk Scheduler uses a simple FCFS queuing algorithm.

The Scheduler base class presents a uniform interface for the scheduling of Jobs. It also maintains statistics about the queue length of the scheduler. Class RRScheduler is the provided CPU scheduling class (you will create the others). It maintains its Jobs in a simple FIFO queue and always chooses the Job at the front of the queue for the next CPU access. The reschedule() method always returns true because jobs are always rescheduled at the end of a quantum, and the add() method always returns false because jobs are not preempted by new arrivals. DiskScheduler: You don't need to worry about the disk scheduler for this assignment. In brief, it maintains a FIFO queue of jobs and will provide access to the disk in a FCFS (First Come First Served) order.

Main Loop

The main loop (found in Sim.java) cycles waiting for interrupts from the various devices. When one occurs, the loop handles it as described earlier. The picture below shows the main loop waiting on the various types of devices that can interrupt.

An informal trace of the main loop's code follows:

Input File

The simulation is driven by a trace file generated from an actual Unix system. The lines of the trace file are sorted by program starting time and are of the form:

Trace File Example:

Statistics and Debugging Output

On termination, the simulation prints are large number of statistics about the run, including

A log of significant events is also provided if the -v flag is included on the command line. The -v may be repeated. One -v traces job arrivals and departures. Two -v's adds events when jobs become blocked or ready. Three -v's call for a trace of all events, including clock interrupts. It also causes jobs to be indicated in a more verbose format:

indicates that job tcsh, which was the third job to arrive, arrived at time 0:00:00.080 (zero hours, zero minutes, zero seconds, and 1000 milliseconds after start-up). It needs a total of 3.5 seconds of CPU time, of which 3.266 seconds remain. The current burst has 234ms of time remaining. Of a total of 15 I/O operations, 14 remain. Four -v's prints all queues each time around the main loop.

The -t option requests a trace of significant events for each job (printed when the job terminates) and for each device (printed at the end of the simulation). This option slows the simulation considerably, so you might want to use a shortened version of the data file.

Last modified Sun Nov 23 08:49:20 CST 1997

Copyright © 1996, 1997 by Marvin Solomon. All rights reserved.