In this project, you will do the following:
WARNING: Do not view the starter code for this project before completing the previous one. Doing so is a violation of the honor code.
The spawn() system call should create a new running process.
First, it must look up a process by name. Since we have not yet implemented file systems, you are provided a dummy filesystem defined in ramdisk.h. The test cases each define their own files.
You may assume a finite number of running processes (NUM_PCBS).
Return the pid on success, -1 if unable to find the process, -2 if there are too many processes.
Processes will be able to communicate via first-in, first-out message box queues. These queues should be an efficient implementation of the bounded-buffer problem.
Message boxes support four operations, each with a corresponding system call:
Neither do_mbox_send() nor do_mbox_recv() should call enter_critical() or leave_critical() directly.
You will write a handler for irq1. This handler will receive bytes from the keyboard, and buffer them using a message box. If the keyboard buffer is full, the handler must instead discard the character.
You must also implement the get_char system call. This system call will try to read a character from the keyboard buffer, or block until one is available.
To aid in your debugging, the initial code distribution contains a dummy implementation of get_char. This implementation repeatedly types out the strings:
The kill() system call should change the state of a process such that it will die (soon). Special care must be taken in certain circumstances; for instance, there may be difficulties if this process is not in the ready queue. Think about this problem, and discuss your solution at design review.
When a process is killed, no effort should be made to release any resources that it holds (such as locks).
The kill system call should immediately kill a process, even if it is sleeping or blocked (even on a wait() call). If a process is killed while sleeping, other sleeping processes should still wake on schedule. If a process is killed while blocked on a lock, semaphore, condition variable or barrier, the other processes which interact with that synchronization primitive should be unaffected. If a process is killed while it is in the ready queue, lottery scheduling should still give proportional scheduling to the surviving processes.
If a process has opened message boxes, their usage counts should be decremented when a process is killed.
The wait() system call should block the caller until a given process has terminated. Your implementation must be efficient.
The source code is distributed with two test cases:
To select a test case, use the settest script just like in project 3.
Writing your own, more specific test cases is recommended. Don't forget to test the final version via USB!
When you have finished the project, the test_given test should look similar to this:
(Pictured: shell (test_given) mid-execution, as the plane mows down the help text)Submit via dropbox (only one person should submit per group). When you submit, you should submit a README and all files that you modified. Do not submit a modified Makefile.
Double check that you've included all modified files when you submit! Submissions that fail to compile for any reason will incur a penalty.