CS 537-2: Spring 2000
Programming Assignment 3
CPU Scheduling

Code Due: Wednesday, March 29th at 8:50am -- CHANGED!!

Report Due: Wednesday, March 29th at start of discussion section

No demos for this project

Contents


Objectives

There are three main objectives to this assignment:

  1. To exercise your ability to work from an existing code base.
  2. To learn about CPU scheduling, in particular, the reasons for different mechanisms within Solaris Time-Sharing.
  3. To measure and analyze performance of different scheduling policies, demonstrating your ability to scientifically investigate system behavior.

Introduction

We have written a program that simulates a short-term CPU scheduler; with this program, you can experiment with various scheduling policies. Your assignment is to measure and analyze the performance of several policies, modifying the simulation program as necessary.

An important component of this assignment is not only to create an implementation that works correctly, but to demonstrate that functionality to us through experiments and a written report. You will be graded on your methodology and reasoning as well as your conclusions.

System Overview

The Simulator essentially consists of Jobs, Devices, and Schedulers -- all coordinated by a single loop of code. A Job is a customer of services: it is a process that needs to use system resources during its execution. A Device represents a resource in the system. In this simulation, the devices available to a job are the CPU and the disk. There is also a clock device and a pseudo-device that interrupts whenever a new job arrives in the system. A Scheduler coordinates access to a device. It queues Jobs that are waiting to use a device and will choose which job is the next to access.

The overall execution of the simulator occurs like this: Jobs arrive at the JobArrival device and are entered into the system. A job's lifetime consists of alternating periods of using the CPU (called a burst) and performing I/O. The Main Loop is responsible for moving jobs around the system. It sends them to a scheduler, takes the next job from a scheduler, and starts and stops jobs running on a device. The Disk Scheduler and the CPU Scheduler decide which job should be the next to run on their respective devices. They also buffer jobs that are waiting to run but have not yet been given access. The clock device is used to enable preemption (more on this later).

For those who would like a more detailed description of the system (more than is necessary to do this assignment) there is the following description, JavaDoc pages describing all the interfaces and, of course, comments in the code itself.

Running the Simulator

The current version of the program simulates (non-preemptive) Round-Robin (RR) scheduling, but it is constructed to allow easy modification for other scheduling policies. The program expects the following command line:

java Proj3 [-v...] [-t] data-file quantum

You should add another required field.

java Proj3 [-v...] [-t] data-file quantum dispatch-table-file

Program Modification

For this project, you are going to be focusing almost exclusively on the CPU Scheduler object shown above. The provided simulator performs Round-Robin (RR) scheduling. You are to create separate versions of the simulator to implement each of the CPU scheduling algorithms described below. Your final version will be an accurate model of the Solaris Time-Sharing scheduler; the earlier versions will be incomplete models of the Solaris scheduler, for which you can demonstrate certain weaknesses. For more details of the Solaris Time-Sharing scheduler, you should read the Lecture Notes.

  1. Version 1 (TS1Scheduler):
    (a)
    Jobs are scheduled according to priority, which ranges from 59 (highest priority) to 0 (lowest priority).
    (b)
    When a job enters the system, it begins at priority 29.
    (c)
    The scheduler maintains a queue of jobs for each priority level; in some cases jobs are added to the head of the queue, in other cases the tail. The scheduler will always run the job at the head of the highest priority queue available (i.e., highest-numbered non-empty queue). For example, if queues 59 and 58 are empty but queue 57 is not, the scheduler will run the first job in queue 57.
    (d)
    The scheduler is preemptive. If a higher-priority job becomes ready while a lower-priority job is running, the higher-priority job should be immediately scheduled. The lower-priority job should be returned to the head of its queue.
    (e)
    When a job is run, it is assigned a time-slice, which is a number of quanta based on the priority of the job. The length of the time-slice should be that specified in the dispatch table given on the input line. The format of this file should match that of Solaris, even though not all of the fields will be used in every version of your scheduler. To get this file on your system, run the command
               /usr/sbin/dispadmin -c TS -g
    
    Note that all time is in units of milliseconds in the simulator.
    (f)
    Once a job uses up its time-slice, the scheduler stops it, lowers its priority, and adds it at the tail of the new queue. A new job may be selected to run at this point. The new, lower priority should be the same as specified in the Solaris dispatch table.
    (g)
    When a job re-awakens after it has blocked, its priority should be raised to the level specified in the Solaris dispatch table. This change in priority should always occur, regardless of the amount of time the job was blocked.

  2. Version 2 (TS2Scheduler): This version is the same as version 1, except rule (g') dealing with blocked jobs is modified.
    (g')
    When a job re-wakens after blocking, its priority is raised if and only if the job's value of dispwait is greater than the value specified in the Solaris dispatch table for maxwait. Adding this functionality requires adding the routine update(), which runs once a second, incrementing dispwait for each job. dispwait is cleared whenever a job finishes its time-slice. Since maxwait=0 in the default dispatch table, the priority of a process is raised if it was sleeping when update() ran. However, your code should work for higher values of maxwait.

  3. Version 3 (TS3Scheduler): This version is the same as version 2, except a new rule (h) is added.
    (h)
    If a job is determined to be starving, then its priority should be raised to the amount specified in the dispatch table. A job is labelled starving if its value of dispwait ever exceeds that of maxwait.

You should have four versions of the simulation program when finished,

Files

The files you will need can be found in

    ~cs537-2/public/Project3
They include all of the files for the simulator, several data files, and a Makefile. Copy all of these files into one of your directories and type make to run the Round-Robin version of the simulator.

Coding

The easiest way to attack this assignment is to modify a copy of the provided Round-Robin scheduler.


    cp RRScheduler.java TS1Scheduler.java
Don't forget to change all occurrences of RRScheduler to TS1Scheduler in the copy and in Makefile.

You should also change the line cpuScheduler = new RRScheduler(); in the file Sim.java to read cpuScheduler = new TS1Scheduler();. The methods in RRScheduler which you will have to modify for your assignment include:

You may also need to modify the Job class, for example to add a field to keep track of the job's priority.

Experiments

You will show the problems that can occur if some of the components of the Solaris Time-Sharing scheduler are not implemented. You will also show how to systematically alter scheduling performance by making changes to the dispatch table.

If the program is not printing out all the statistics you would like to see, feel free to modify it to produce better output. You will find that additional statistics are necessary to demonstrate the following phenomena.

  1. Version 1: Demonstrate that a job can game your first version of the TS scheduler; that is, a job can receive more than its fair share of the CPU by altering its behavior. Create a data-file that shows that jobs which block for a very short period of time can complete faster than jobs which are completely CPU bound. Name this data-file GAME.txt. Show output from your simulator that will convince us that these jobs receive more than their fair share of the CPU.

    You will want to add an optional fifth field to the data-files to test this functionality. Currently, the format is:

    The amount of time for each I/O operation is set as a fixed constant as Sim.DISK_TIME = 20ms. Change this so if a fifth (integer) field is present, then it specifies the time (in milliseconds) for each I/O operation. If it is not specified, then the default value of Sim.DISK_TIME should be used. This will require a few small changes to the Job class as well as the call to disk.start().

  2. Version 2: Use the same data-file, GAME.txt, as input to your second version of the TS scheduler. Show output that will convince us that jobs which block for a very short period no longer complete faster than jobs which are completely CPU bound.

  3. Version 2: Demonstrate that some jobs can starve with this scheduler. Create a data-file, STARVE.txt, that shows that a job which is completely CPU bound may never be scheduled if there are many competing jobs which block. Note that since the data-files for this simulator contain a fixed number of jobs to run, it is impossible to forever starve any job; when all of the other jobs in the workload complete, the "starving" job will get to run. Therefore, your output should show that the "starving" job has a waiting time approximately equal to the completion time of the other jobs.

  4. Version 3: Use the same data-file, STARVE.txt, as input to your third version of the TS scheduler. Show output that will convince us that compute-bound jobs no longer starve.

  5. Version 3: There are three steps to this part.
    1. For the default dispatch table, show for each of the two input data files we provide (DATA1.txt, DATA2.txt) the following statistics:
      (a)
      completion time,
      (b)
      throughput,
      (c)
      average job elapsed time,
      (d)
      average job waiting time.

    2. Create two dispatch tables that perform worse on as many of these metrics as possible. Explain which metrics can be made worse. Each dispatch table should change a different column from the default table. Each dispatch table should perform worse for both of the given data files. Put the two dispatch tables in files called WORSE1.dpt and WORSE2.dpt. Show us the four statistics for the two data files and the two dispatch tables. Explain why your changes to the table made performance worse.

    3. Advanced: Create a dispatch table that performs better on as many of these metrics as possible. We do not know how difficult it will be to improve performance over that of Solaris; since this may be arbitrarily difficult, it will be very important that you describe the steps that you took to try to solve this problem. Points will be given for methodology and reasoning, not just for the final answer.

      If needed, you may specifiy a different dispatch table that improves the performance of each input file. If you have a single dispatch table, name it BETTER.dpt. If you need two different tables, name then BETTER1.dpt and BETTER2.dpt. Again, show the statistics for each data file and explain why your changes to the table improved performance.

You should approach the experiments for this project as you would approach a laboratory assignment in a physics course. Use the ``scientific method.'' You should form some hypotheses before you start experimenting and use the experiments to confirm or reject these hypotheses based on observed results. It's not the quantity but the quality of your statistics that dictates the quality of the experiments.

Give careful thought to the correct choice of parameters for the programs. If you can't explain why performance changes, you should find parameters to change that you can explain.

Report

You are to prepare a report describing the results of your experiments. Again, approach this report as you would approach a physics laboratory experiment report. You should carefully describe what experiments you did and what the results showed you. We want to see a correlation between the experiments you run and the conclusions you draw. You must supply quantitative data to support your conclusions.

Your report should be no longer than three pages, not including any tables or graphs you wish to add. You should put your modified dispatch tables and your statistics into tables (or graphs) in the report. You should summarize the input data files, GAME.txt and STARVE.txt, in report as well.

Grading

There will be no demos for this project. Your grade will be determined as follows:

You must work in two-person groups for this project.

Handing In

You should put a copy of your code (.java files only) in the appropriate subdirectory of ~cs537-2/handin. Create a separate sub-directory for each version of your program, and include in each directory all .java files needed to build the program (even the parts we wrote and you didn't change). Include all dispatch tables as well as GAME.txt and STARVE.txt. Do not include .class files or copies of our data files. Be sure each file contains the names of both partners.

Bring a printed copy of your report to class the following day. As stated above, the report should be at most three pages, not including graphs and tables. Don't forget to put the names of both partners on the printed report.