CS 377: Operating Systems - Project 2

Due: Friday, November 2 @ 9 pm EDT

UMass Computer Science, Fall 2012 [Course homepage]


MLFQ CPU Scheduler

By default, the Nachos kernel uses a simple round-robin CPU scheduler to manage multiple kernel threads. In this project, you will implement a multilevel feedback (MLFQ) scheduler to improve average response times for mixed CPU and I/O bound workloads.

Getting the starter code

While your experience working with Nachos in lab 1 will be helpful, you do not need to start from your existing codebase. Instead, we will provide a version of Nachos that is more complete than in part 1 (particularly with regard to threading). Download the starter code:

$ wget http://lass.cs.umass.edu/~shenoy/courses/377/labs/2/nachos-mlfq-starter.tar.gz
$ tar xzvf nachos-mlfq-starter.tar.gz

For this lab, you will be working exclusively in the nachos.threads package. This package implements threading and CPU scheduling within the Nachos kernel. You may wish to look through KThread.java to see how Nachos switches between threads and sets their status as in the state flow diagram discussed in lecture (new/ready/running/blocked/finished).

  1. In lab 1 (part B), we worked from the proj2 directory within Nachos. In lab 2, we will be working from the proj1 directory within Nachos. The provided proj1 code simply executes a self-test of the Nachos kernel, followed by some tests of the CPU scheduler. As in lab 1, run 'make' followed by '../bin/nachos' to execute Nachos.
  2. The starter code includes a working round-robin CPU scheduler, which you can use as a model of how to design your scheduler. The existing scheduler is located in RoundRobinScheduler.java. You will implement your scheduler in MultilevelFeedbackScheduler.java. This file already contains a code skeleton and extends the Scheduler class, but does not contain any of the logic actually implementing MLFQ scheduling. To test that your scheduler is working, you will also write test code in MultilevelFeedbackSchedulerTest.java. The test code in this class is automatically executed by Nachos when you run using the MLFQ scheduler. The equivalent RR test class is RoundRobinSchedulerTest.java - this test code executes when you execute proj1 using the default RR scheduler. You should not modify any other of the Nachos files included in the starter code (but feel free to add debugging statements wherever you wish).
  3. The scheduler used by Nachos is specified in proj1/nachos.conf. Change the value of ThreadedKernel.scheduler within nachos.conf to switch between the default (RR) scheduler and your MLFQ scheduler.
  4. The abstract Scheduler class (which your scheduler extends), defines two methods that your scheduler must implement - newThreadQueue() and timerInterrupt(). The former should return a queue used to hold threads waiting on the CPU, and is only called once, early on while initializing the Nachos kernel. The latter is called every few hundred ticks by the hardware timer, and returns whether the currently executing thread should yield or not. Refer both to the Javadocs for these methods and the existing implementation in the round robin scheduler to understand how these methods work.
  5. Implement your multilevel feedback scheduler with three ready queues: RQ0, RQ1, and RQ2. When a thread T first enters the system, it is put in RQ0. When T is eventually placed in the Running State, if it executes until the end of its assigned time slice, it is placed in RQ1 (back in the Ready State). T is demoted to RQ2 if once again it executes for the duration of the next time slice assigned to it. A process that is blocked before it consumes its entire time slice is promoted, i.e., it is moved to the next-highest priority queue. Scheduling is done on a preemptive basis. RQ0 is the highest priority queue; RQ1 is the next highest; RQ2 is the lowest priority queue. Within each priority queue, preemptive round-robin scheduling is used.
  6. The time slice for RQ0 should last for two timer interrupts (each timer interrupt is separated by roughly 500 ticks). Design your system such that the time slice for RQ1 is twice as long as the time slice for RQ0, and the time slice for RQ2 is twice as long as the time slice for RQ1. Note that you don't need to preempt threads in the middle of a timer interrupt (e.g., if a new thread arrives), since timer interrupts are the basic measurement unit of timeslices.
  7. Finally, your MLFQ scheduler should support aging. The goal is to promote a process to a higher-priority queue if it spends a certain amount of time waiting in its current queue for service. Aging is an effective technique for dealing with possible starvation associated with multilevel priority queues. If a thread is not scheduled for at least 32 timer interrupts, your scheduler should promote its priority.
  8. Your test code should demonstrate that your scheduler is working correctly, including mixing CPU and I/O intensive workloads and aging to avoid workload starvation. Tips on writing your test code are given below.

General Tips

Testing Your Scheduler

To test your implementation of a multilevel feedback scheduler, you need to create multiple threads in the Nachos kernel. You should simulate CPU-bound as well as I/O-bound threads in your tests. However, since we are only running kernel-level threads, we do not have real preemption and need to simulate both CPU and I/O computation in our test code. Take a look at RoundRobinSchedulerTest.java to see an example of launching multiple KThreads and simulating both CPU and I/O workloads, as briefly described below.

To simulate CPU-bound workloads, we can simply advance machine time using the Machine.interrupt().tick(duration) method. Note: This method should only be used in testing code, and not within your scheduler itself. Also note that since this is a kernel thread running without preemption, putting something like a regular long-running computation loop in your code will simply block Nachos - using the tick method instead allows for the timer interrupts to fire.

To simulate I/O, you can use the waitUntil(duration) method of the Alarm class, which can be accessed through the static field ThreadedKernel.alarm. This method will block the current thread until the given machine time duration has passed.


How to Turn in Project 2

All of the following files must be submitted on Moodle as a zip file to get full credit for this assignment.
  1. Your zip should contain MultilevelFeedbackScheduler.java, MultileveFeedbackSchedulerTest.java, and any additional files you added yourself. You should not have modified any other Nachos files in any substantial way.
  2. Your zip should also include a README file containing an outline of what you did. It should also explain and document your design choices. Keep it short and to the point. If your implementation does not work, you should document the problems in the README, preferably with your explanation of why it does not work and how you would solve it if you had more time. Of course, you should also comment your code. We can't give you credit for something we don't understand!
  3. Finally, each directory should contain a file showing sample output from running your program (which, in this case, is your test code).
  4. Note: We will strictly enforce policies on cheating. Remember that we routinely run similarity checking programs on your solutions to detect cheating. Please make sure you turn in your own work.

    You should be very careful about using code snippets you find on the Internet. In general your code should be your own. It is OK to read tutorials on the web and use these concepts in your assignment. Blind use of code from web is strictly disallowed. Feel free to check with us if you have questions on this policy. And be sure to document any Internet sources/ tutorials you have used to complete the assignment in your README file.


Project 2 Grading scheme

Late Policy: Project 2 is due at 9 PM on Friday, November 2. Please refer to the course syllabus for late policy on labs assignments. This late policy will be strictly enforced. Please start early so that you can submit the assignment on time.