You can find the original homework document here (or here). This homework assignment is 14% of your final grade. The deadline has been extended to 11:59pm, Saturday November 22nd.
To receive full credit, you must complete everything listed in the homework document. Here is a summary:
- Have well commented code
setLotteryTickets as defined in the homework document
- Modify process creation/deletion to update total amount of tickets assigned
fork to fail when no more tickets remain in system
- Implement lottery scheduling
New: The actual distribution of percentage points will be as follows:
- 2% Documentation (1,2)
- 8% Allocation of tickets (3,4,5)
- 4% Lottery scheduling (6)
The numbers in parentheses indicate which item(s) from the summary list fall under that category. For example, items 1 and 2 from the above summary are included in the 'Documentation' section.
We will be doing interactive grading for this homework assignment. Interactive grading will take place in the Kemper Hall TA Room (same location for the TA office hours). There are several things you can do to make sure this process goes smoothly:
- Name your user-level library function
stattest.c already in your Minix system
stattest.c to use your libary file
- Have your kernel modifications already compiled and working
You may bring your laptop for interactive grading. Otherwise, you must have your modifications working on your CS account. Sign-up sheets will be located outside the TA room in Kemper Hall.
NEW: Interactive grading signup sheets will be posted Wednesday (11/19) evening. Eric will be holding interactive grading sessions from 8:00am - 12:00pm on the following days:
- Tuesday, November 25th
- Monday, December 1st
- Tuesday, December 2nd
- Wednesday, December 3rd
Sophie will be holding interactive grading sessions from 1:30pm - 5:30pm on the following days:
- Sunday, November 23rd
- Wednesday, November 26th
- Wednesday, December 3rd
- Friday, December 5th
In addition to interactive grading, you are required to submit some files using
handin. We may be using Moss to detect cheating.
There are three things total that you must submit using
handin. The files are:
The readme should contain the following information:
- Basic information, such as your name, student id, and the date.
- One or two paragraphs on how you implemented
setLotteryTickets and lottery scheduling.
- List of what modifications you made to
proc.c, so that we can easily find your code.
From your CS account, execute the following command to submit your files:
handin cs150 hw2 system.c proc.c readme.txt
Note: You must submit the actual files, NOT
floppy.img. Details on how to get the files off of Minix are below:
Use a physical floppy drive to transfer the files off of your Minix system.
First you must copy
proc.c onto a physical floppy disk. How this is done depends on the floppy disk you use. For a Minix-formated floppy, you do the following:
mount /dev/fd0 /fd0
cp /usr/src/kernel/system.c /fd0
cp /usr/src/kernel/proc.c /fd0
You can use
mtools if you have a Windows/DOS-formated floppy. Instructions for
mtools are as follows:
mtools copy /usr/src/kernel/system.c A:/
mtools copy /usr/src/kernel/proc.c A:/
You do not need to mount using
mtools. More information on mounting/formatting a floppy in Minix can be found here.
Next you need to retrieve the files on your physical floppy disk. Make sure you are not running Bochs/Minix to avoid resource sharing conflicts. If you are on a Linux system, you should be able to mount the Minix-formated floppy disk. If you are on Windows, you should be able to just access your floppy drive. Once you can access your floppy disk, copy
proc.c to your system.
If you are not using your CS account for homework 2, you will now have to transfer
proc.c to your CS account using
sftp. More information on remote access can be found in the Resources section.
Once the files are on your CS account, you can submit using
handin (see above). Here are some screenshots illustrating this entire process:
If you do not have a floppy disk or are unable to complete this process, please contact one of the TAs for help.
We will use several programs to test your implementation. Below are some sample test programs we may use:
systest.c (updated 14 november 2003)
- Tests to make sure
fork() fails when the maximum number of tickets have been allocated
- Tests to make sure that tickets are reclaimed by the system when a process dies
systest2.c (updated 14 november 2003)
- Similar to
- Requires a system call
getTotalTickets to get the total number of tickets currently assigned
- Carefully tests how the number of tickets assigned gets updated when processes are created and destroyed
- This version will not be used to grade your homework, since it requires
getTotalTickets to be implemented (which is not a requirement of homework 2)
stattest.c (updated 18 november 2003)
- Tests lottery ticket scheduling
- Read comments for usage information
You can download a floppy image with the test programs already on it here. You should try running these programs to test your implementation of
setLotteryTickets() and lottery ticket scheduling.
setLotteryTickets( PID, tickets )
The system call
setLotteryTickets( PID, tickets ) should assign a total of
tickets to the process, not add the amount of
tickets to the number of tickets already assigned to the process. For example, if process pid
20 tickets currently, and the call
setLotteryTickets( 4, 10 ) is made, process
4 should end up having
setLotteryTickets( PID, tickets ) should return the number of tickets assigned to the process, even if it is less than
tickets. The value of
-1 should be returned only if
setLotteryTickets(...) failed due to an error. Read the homework document for more information.
10 tickets, and that the maximum number of tickets have already been assigned. Then
setLotteryTickets( 4, 20 ) should return
10 tickets can be assigned to process
4 already has
10 tickets allocated to it). However,
fork() should return
-1 at this point since there are no more additional tickets left in the system for a new process.
Regarding ticket assignment
When deciding if more tickets may be assigned, you must compare
MAX_TICKETS. The maximum number of tickets (
MAX_TICKETS) is defined as
256 in the homework document. The value of
num_assigned should include the number of tickets for all user processes (whether the process is in a ready or wait state). See Hints & Tips for more information.
Regarding lottery scheduling
You should only attempt to schedule user process that are in the ready state.
When choosing a random number, you should choose a number in the range of
max is the total number of tickets assigned to ready processes. You should not include the number of tickets from processes that are in a wait or non-ready state in the calculation of
Homework Hints & Tips
Various guides and slides have been created to help with homework 2. You can find these here:
Tracking Total Assigned Tickets
You will have to track how many tickets have been assigned for various parts of this homework assignment. It may be helpful to create a system call (in the same manner as you will create
setLotteryTickets) that returns the total number of tickets assigned in the system. However, you must be careful what processes you include. When determining if
fork() should fail, you should count the number of tickets for all user processes (even those that are not in a ready state). When you are doing lottery scheduling, you should count the number of tickets for ready processes only.
Looping Through Processes
When searching for a process pid, counting tickets, etc., you will need to loop through processes. There are a couple of ways to do this, depending on what processes you want to loop through.
Using Pointers: To loop through ready processes only, you can make use of
rdy_head[USER_Q] and the attribute
p_nextready. You might also want to make use of
NIL_PROC. Look at page 117 of your book, and in
proc.h for more information.
Using the Process Table: To loop through the entire process table, you can simply iterate through
proc. However, you have to figure out where to start the iteration and where to end the iteration. Where to end is easy - as we know the size of
NR_TASKS + NR_PROCS. Where to start iteration is a little more tricky. We do not want to loop through tasks, and want to start our loop at the first user process. Here are a few hints: What is the first user process? What is happening on line
06817 in your book's source code (page 603)?
When looping through
proc, we also have to be wary of empty slots. Not every slot has valid process information. If the slot is not being used, we do not want to include that slot. Therefore we will also have to test for this. Look at
/usr/src/kernel/proc.h and examine the attributes
p_priority. Also look at the macros contained in
proc.h. Some of this stuff is omitted from the source code in your book, so be sure to look at the actual files on your Minix system.
Writing the System Call
You should write the system call
setLotteryTickets(...) in an iterative manner. First get a simple system call which resides in
MM working. Then add a system call that makes a task call to the kernel. Lastly, add the actual functionality that the system call must accomplish. Here are a few hints that may help you along the way:
- Be careful of how you name your parameters. For example,
pid is defined in
PID is defined in
- You must pass parameters using messages for this system call. The message
m1 should satisfy your needs. Read more in your book (pages 109-110) or examine
- You can call
_taskcall(...) straight from
MM without having to add another library function. Just be sure to include
- Define a constant
MAX_TICKETS as the maximum number of tickets the system can support. You should place this such that both kernel and the servers (
FS) can access the constant. Hint: You may want to look at where the constant
NR_PROCS is used and where it is defined.
Tickets and Process Creation, Deletion
You have to modify process creation (
fork) and deletion (
exit) to take in account the number of tickets assigned in the system. If you constantly calculate the number of tickets assigned versus keeping a global variable, you will not have to worry about process deletion. Otherwise, when a process dies it must subtract its tickets from the number of tickets assigned.
There are two things you must worry about when it comes to process creation. First you must decide if
fork() should fail based on how many tickets are already assigned in the system. If there are no more tickets left,
fork() should return
-1. You want to make this check before memory is allocated for the new process. Refer to the lecture 2 slides for more information on
Second, you must initialize the number of tickets for a new process to
1. You may want to do this in the same place that
fork() initializes the child pid.
One last thing... you may have to worry about initializing the number of tickets for
init is not a result of a
fork() since it is the first/initial user process. Hint: Look at
The first thing you should do is read the section "Scheduling in MINIX" on page 140 of your book and get familiar with
proc.c, and understand lottery scheduling in general.
Suppose we have the following ready queue of user processes, where the bold number on top is the
pid and the blue number on bottom is the number of tickets that process has:
To schedule the next process using lottery scheduling, we would first choose a random number. In this example, the total number of tickets assigned to a ready process is
36. Therefore we choose a random number between
36. Starting at the beginning of the queue, we count up the number of tickets assigned to each process until the count is greater than or equal to our random number.
Suppose our random number is
14. We count the tickets of processes
12 such that our count becomes
1 + 1 + 10 + 4 = 16 >= 14. Since our count became greater than or equal to our random number when we reached process
12, we let process
12 run next.
Now suppose we have to make a new scheduling decision, and our random number is
4. Using the implementation described above, process
7 would be scheduled to run next. The following picture provides the range of numbers that allow a particular process to run:
For example, process
12 will run whenever our random number is between
4 will run only when the random number is equal to
NEW: If you get a
divide by zero error after implementing lottery scheduling - you are most likely trying to
mod something by zero. Depending on your implementation, lottery scheduling may be called before there are ANY tickets assigned in the system (thus the total number of tickets will be zero). You may have to add code to lottery scheduling to handle this!
NEW: If you are modifying the ready queue of processes, you will have to update the
p_nextready links in the queue. There are three different cases that you have to check for. They are:
- Process is rdy_head[USER_Q]
- Process is rdy_tail[USER_Q]
- Process is located somewhere in the middle of the queue
After adding an attribute to
struc proc, running
ps to display running processes may return junk to the screen. There are two ways to get around this:
- You can always press
F1 for a screen-dump of the running processes.
- You can recompile/reinstall
ps. This process does not take very long. Just type
make ps and
make install while in
NEW: Sometimes the kernel is not updated after you run
make hdboot. (You may see a message similar to:
2.0.3r7 is up to date.) To remedy this situation you can try a few different things:
- Delete the file
# is the latest revision number.
- Delete the file
- Use a fresh installation of Minix.
After trying one of the above items, you should be able to type
make hdboot to actually recompile/install the new kernel.