Project 2b: xv6 SchedulerUpdatesUpdates will be added here if need be. Please check periodically.
ObjectivesOverviewIn this project, you'll be implementing a simplified multi-level feedback queue (MLFQ) scheduler in xv6. The basic idea is simple. Build an MLFQ scheduler with four priority queues; the top queue (numbered 3) has the highest priority and the bottom queue (numbered 0) has the lowest priority. When a process uses up its time-slice (counted as a number of ticks), it should be downgraded to the next (lower) priority level. The time-slices for higher priorities will be shorter than lower priorities. The scheduling method in each of these queues will be round-robin, except the bottom queue which will be implemented as FIFO. To make your life easier and our testing easier, you should run xv6 on only a single CPU (the default is two). To do this, in your Makefile, replace DetailsYou have two specific tasks for this part of the project. However, before starting these two tasks, you need first have a high-level understanding of how scheduler works in xv6. Most of the code for the scheduler is quite localized and can be found in Now to implement MLFQ, you need to schedule the process for some time-slice, which is some multiple of timer ticks. For example, if a process is on the highest priority level, which has a time-slice of 8 timer ticks, then you should schedule this process for ~80ms, or equivalently, for 8 iterations. xv6 performs a context-switch every time a timer interrupt occurs. For example, if there are 2 processes A and B that are running at the highest priority level (queue 3), and if the round-robin time slice for each process at level 3 (highest priority) is 8 timer ticks, then if process A is chosen to be scheduled before B, A should run for a complete time slice (~80ms) before B can run. Note that even though process A runs for 8 timer ticks, every time a timer tick happens, process A will yield the CPU to the scheduler, and the scheduler will decide to run process A again (until its time slice is complete). 1) Implement MLFQYour MLFQ scheduler must follow these very precise rules:
2) Create new system callsYou'll need to create one system call for this project:
int getpinfo(struct pstat *)
Because your MLFQ implementations are all in the kernel level, you need to extract useful information for each process by creating this system call so as to better test whether your implementations work as expected.
To be more specific, this system call returns 0 on success and -1 on failure. If success, some basic information about each process: its process ID, how many timer ticks have elapsed while running in each level, which queue it is currently placed on (3, 2, 1, or 0), and its current struct pstat { int inuse[NPROC]; // whether this slot of the process table is in use (1 or 0) int pid[NPROC]; // PID of each process int priority[NPROC]; // current priority level of each process (0-3) enum procstate state[NPROC]; // current state (e.g., SLEEPING or RUNNABLE) of each process int ticks[NPROC][4]; // number of ticks each process has accumulated // RUNNING/SCHEDULED at each of 4 priorities int wait_ticks[NPROC][4]; // number of ticks each process has waited before being scheduled };The file can be seen here. Do not change the names of the fields in pstat.h .
TipsMost of the code for the scheduler is quite localized and can be found in
As part of the information that you track for each process, you will probably want to know its current priority level and the number of timer ticks it has left. It is much easier to deal with fixed-sized arrays in xv6 than linked-lists. For simplicity, we recommend that you use arrays to represent each priority level. You'll need to understand how to fill in the structure
To run the xv6 environment, use The CodeWe suggest that you start from the source code of xv6 at Particularly useful for this project: Chapter 5 in xv6 book. TestingTesting is critical.
Testing your code to make sure it works
is crucial. Writing testing scripts for xv6 is a good exercise in itself, however, it is a bit challenging. As you may have noticed from p1b, all the tests for xv6 are essentially user programs that execute at the user level. You may refer to these C programs in For this project, we only release part (~90%) of the tests. This is a good chance to practice creating test cases and think comprehensively! (Hint: Think about programs that stay in a loop, sleeping for varying amounts of time.) That said, we still provided some descriptions about the workload and expected behaviors for the hidden test cases, which can be found in |