Project 4: Scheduler - MUFiX
Assignment Day | September 29, 2009 (Tuesday - midnight) |
Due Date | October 13, 2009 (Tuesday 5 PM, but no penalty until the start of October 14). |
Collaboration Policy - Read Carefully
You can work on this project with a partner, andyou are encourage to discuss the assignment with other students or teams on the email list. You may consult (but not copy) any outside resources you including books, papers, web sites and people (but no penguins or sea urchins).
If you use resources other than the class materials, indicate what you used along with your answer.
You have probably guessed it by now - every project will have a similar paragraph to the one above but with slight variations, of-course.
Objective:
The main objectives for this project are:
- Learn about scheduling
- Get more experience with a real operating system
The main goal for this project is to modify the MINIX 3 scheduler to be more flexible. To achieve this goal you must implement:
- A multi-level feedback-based scheduler and
- a lottery scheduler
This tutorial/project is inspired by Darrel Long and used by permission and many others.
Tutorial / References
MINIX resources programming/tutorials:There are several MINIX resources that I found useful. http://en.wikipedia.org/wiki/MINIX_3 (see great links at bottom). http://www.minix3.org/doc/A-312.html (outlines the process nicely) http://wiki.minix3.org/en/UsersGuide/DoingInstallation (newer and above, but the first listed is still useful). http://wiki.minix3.org/en/UsersGuide/RunningMinixOnVmware(insights on running MINIX on WMware. http://www.minix3.org/manpages/index.html (Minix man pages) VMWare resources programming/tutorials:http://www.vmware.com/products/player/ (free VMware player) http://www.vmware.com/products/fusion/ (WMWare for mac and it links to 30-day trial - we are hoping to get/setup a 12 months license for our are waiting for an approval for this - it looks like a possibility right now - please email me if you are interested in this). |
If you find other resources please post links on the mailing list for the class. |
Background:
As previously mentioned this project will teach you how to experiment with a real operating system kernel(s)- and as a consequence you will learn to work in such a way that deals with a computer crashes (well not quite) and / or end up with an OS that doesn't work.We suggest that you manage multiple kernels, and always have access to at least one working kernel. Back up your work frequently and work in small incremental steps.
Basics:
You are to implement a multi-level feedback-based scheduler and a lottery scheduler in your MINIX kernel.
A lottery scheduler assigns each process some number of tickets, then randomly draws a ticket among those allocated to ready processes to decide which process to run. That process is allowed to run for a set time quantum, after which it is interrupted by a timer interrupt and the process is repeated. The number of tickets assigned to each process determines both the likelihood that it will run at each scheduling decision as well as the relative amount of time that it will get to execute. Processes that are more likely to get chosen each time will get chosen more often, and thus will get more CPU time.
The feedback scheduler does a similar thing using multiple queues. To accomplish this goal, you'll need to add 3 more process queues to the MINIX operating system—your modifications should only apply to user processes, not to OS kernel processes.
Details:
Unless explicitly specified, all source code can be found in /usr/src/.
Modifying the scheduler in MINIX should mostly involve modifying the code in kernel/proc.c
specifically the sched()
and pick_proc()
functions (and perhaps enqueue() and dequeue() ). You may also need to modify kernel/proc.h to add elements to the proc structure and modify queue information (NR_SCHED_QUEUES, TASK_Q, IDLE_Q, etc.) and may need to modify PRIO_MIN and PRIO_MAX in /usr/include/sys/resource.h. Process priority is set in do_getsetpriority() in servers/pm/misc.c (don't worry—the code in here is very simple), which calls do_nice() in kernel/system.c. You might be better off just using the nice() system call , which calls do_nice() directly. You'll probably want to modify what do_nice() does—for lottery scheduling, nice() can be used to assign or take away tickets.
The current MINIX scheduler is relatively simple. It maintains 16 queues of "ready" processes, numbered 0–15. Queue 15 is the lowest priority (least likely to run), and contains only the IDLE task. Queue 0 is the highest priority, and contains several kernel tasks that never get a lower priority. Queues 1–14 contain all of the other processes. Processes have a maximum priority (remember, higher priorities are closer to 0), and should never be given a higher priority than their maximum priority. You're going to need to add 3 queues to the existing 16 for a total of 19 queues. The easiest solution is to use the top 16 queues for system processes using the existing code, and to use the bottom 3 queues for user processes. You can identify system processes by seeing if the SYS_PROC bit is set in a process's flag variable.
Lottery Scheduling:
The first approach to scheduling is to use lottery scheduling, as described in the Wednesday's presentation (Dajiang's). System processes (queues 0–14) are run using their original algorithm, and queue 15 still contains the idle process. However, queue 16 contains all of the runnable user processes, each of which has some number of tickets. The default number of tickets for a new process is 5. However, processes can add or subtract tickets by calling setpriority(ntickets), which will increase the number of tickets by ntickets (note that a negative argument will take tickets away). A process cannot accumulate more than 100 tickets.
Each time the scheduler is called, it should randomly select a ticket (by number) and run the process holding that ticket. Clearly, the random number must be between 0 and nTickets-1, where nTickets is the sum of all the tickets belonging to processes in the ready queue (processes that are blocked are ineligible to run). You may use the random() call (you may need to use the random number code in /usr/src/lib/other/random.c) to generate random numbers and the srandom() call to initialize the random number generator. A good initialization function to use would be the current date and time.
New processes are created and initialized in kernel/system/do_fork.c. This is probably the best place to initialize any data structures.
Multiple Round-Robin Queues:
The second algorithm you need to implement uses three round robin queues. Processes are placed into the first queue when they are created. Demotion: Processes are moved to the second queue after they have completed five quanta (that is, after they have been scheduled five times without waiting for I/O first), and to the third queue after they have completed ten quanta. The scheduler runs all of the processes in the first queue once and then runs a single process from the second queue. After all of the processes in the second queue have run, a process from the third queue is selected to run. Promotion: Processes are promoted back into the first queue after they have completed 20 quanta. This can be implemented in several ways; one possibility is to include a “pseudo-process” in the first queue that, when at the front of the queue, causes a process from the second queue to be run (also repeated in the second queue to run a process in the third queue).
Assume the following processes are in the three queues:
- Queue 1: P1 , P2 , P3
- Queue 2: P4 , P5
- Queue 3: P6 , P7
The scheduler would run processes in this order:
P1 , P2 , P3 , P4 , P1 , P2 , P3 , P5 , P6 , P1 , P2 , P3 , P4 ...
This allows long-running processes to make (slow) progress, but gives high priority to short-running processes.
To do this, you should add three additional queues to kernel/proc.c. System processes are scheduled by the same mechanism they use currently, but user processes are scheduled by being initially placed into queue 1, with a later move to queue 2 (or from queue 2 to queue 3). You can do this by modifying sched() and pick_proc() in kernel/proc.c. You might also need to modify enqueue() and dequeue(), and should feel free to modify any other files you like.
Hints
- START EARLY!
- You should start with your design, and check it over.
- Experiment! You're running in an emulated system—you can't crash the whole computer (and if you can, let us know...).
- You may want to edit your code outside of MINIX (using
your favorite text editor) and copy it into MINIX to
compile and run it. This has several advantages:
- Crashes in MINIX don't harm your source code (by not writing changes to disk, perhaps).
- Most OSes have better editors than what's available in MINIX.
- Test your scheduler. To do this, you might want to write several programs that consume CPU time and occasionally print out values, typically identifying both current process progress and process ID (example :P1-0032 for process 1, iteration 32). Keep in mind that a smart compiler will optimize away an empty loop, so you might want to use something like this program for your long-running programs.
- Your scheduler should be statically selected at boot time. However, there's no reason you can't have the code for both lottery and multi-queue scheduling in the OS at one time. At the least, you should have a single file and use #ifdef to select which scheduling algorithm to include.
- For lottery scheduling, keep track of the total number of tickets in a global variable in proc.c. This makes it easier to pick the ticket. You can then walk through the list of processes to find the one to use next.
- Use RCS to keep multiple revisions of your files. RCS is very space-efficient, and allows you to keep multiple "coherent" versions of your source code and other files (such as Makefiles).
- Here are some additional tips to get you started.
- Did we mention that you should START EARLY!
We assume that you are already familiar with makefiles and debugging techniques from your earlier project in this class or from courses such as CS 1730 or the UNIX tutorials held the first week of class by the department. If not (which is unlikely), this will be a considerably more difficult project because you will have to learn to use these tools as well.
This project doesn't require a lot of coding (typically fewer than 250 lines of code), but does require that you understand how to use MINIX and how to use basic system calls. You're encouraged to go to the class discussion section or talk with the course staff during office hours to get help if you need it.
You should do your design first, before writing your
code. To do this, experiment by inserting debugging print statements if it'll help. It
may be more fun
to just start coding without a design, but it'll
also result in spending more time than you need to on the
project.
IMPORTANT: As with all of the projects this semester, the key to success is starting early. You can always take a break if you finish early, but it's impossible to complete a 20 hour project in the remaining 12 hours before it's due....
Project groups
You may do this project with a project partner of your choice. However, you can't switch partners after this assignment, so please choose wisely. If you choose to work with a partner (and we encourage it), you both receive the same grade for the project. One of you should turn in a single file called partner.txt with the name and CATS account of your partner. The other partner should turn in files as above. Please make sure that both partners' names and accounts appear on all project files.
Submitting:
Submitting:
|
Design Document:
Your design document should describe the design of your assignment in enough detail that a knowledgeable programmer could duplicate your work. This includes descriptions of the data structures you use, all non-trivial algorithms and formulas, and a description of each function including its purpose, inputs, outputs, and assumptions it makes about the inputs or outputs. A sample design document is available here.
Grading Criteria: