CSC468 Assignment 2 Post Mortem Total Marks: 100 Design: 30 Marks ---------------- This section was based on you design documentation. If you failed to mention something or your document was vague, I gave you the benefit of the doubt and checked your code. The Foreground and Background Queues 10/30: This was done well in general. You basically had to talk about adding another linked list queue to the schedule monitor. You had to talk about how you were going to get the queues to work as described in the assignment hand out. You should have mentioned how you were going to change the Schedule monitor functions. You also had to talk about how new, yielded, and kernel processes were identified so that they could be put on the correct queue. You should also have mentioned how/where you set the processes timeslice to either ForegTS or BackgTS. The Yield System Call 5/30: This was also done well. All you had to do was talk about how you got this to work. Following the guidelines in the Minotaur documentation was sufficient. Mentioning how you identified a process as yielded was also required (if you didn't mention it already). The Periodic Scanning for Condition A 15/30: This is generally where people lost marks. Though the assignment did not explicitly ask for a Daemon to do this, no one came up with a better way to do it, so you lost marks if you did not have a scanning daemon. Having the kernel do the scanning was not acceptable. Getting the daemon to have the correct scanning period was tricky. There was some debate as to whether or not it was acceptable to modify the CPU code to accomplish this. Since the Minotaur hardware has no timer device (and it should since any real machine would have one), it was acceptable to make VERY minor additions to the hardware to SIMULATE the actions of a timer chip. This means you could add code to CPU_x.b to generate a trap every TimeSlice/2 ticks. I was a bit lenient and let you call a wake up procedure from CPU as well, as long as you did not call a scanning routine right from CPU. If you did call a scanning routine right from the CPU code this is equivalent to rebuilding a CPU chip that did the scanning itself. Since this is a course in operating systems and not a course in CPU design, you lost marks for this. Another way to get the Daemon to run on time, was to set the cpu->timeSlice to TimeSlice/2, and let processes run for two timeslices in a row. This was fine as long as you had some way to address the fact that blocking and yielding processes might cause the Daemon to be late. When the daemon was woken up, it should have been placed at the front of the Foreground Queue. Some groups thought that the Daemon should pre-empt a running process. This was not required and not desirable. First of all since the Daemon will run before any of the other process in the ready queue, it might as well let a currently running process finish. The daemon will (should) lock the Scheduler as soon as it starts running, so no processes will get scheduled while its running. Basically, pre-empting meant added complexity for very little gain. Furthermore, pre-empting processes all the time makes them run slower. So, if you made the daemon pre-empt running processes, you lost marks (but not a lot). Finally, you should have discussed what the daemon did when it ran. You should have outlined how it gathered its stats, how you calculated the system average, and how you move processes that satisfied condition A. You could have lost up to 3 marks if you did not outline which files you added/changed. Implementation: 40/100 This mark reflected how well, your implementation passed some tests including your own. Your code basically had to satisfy all the requirements of the assignment. If your code did not run, you lost up to ten marks. I also scanned through the code to see if you were violating concurrency. ie. accessing the SchedPrev / SchedNext pointers outside of the Schedule monitor. You lost marks if you called "Trap" from within a Trap handler routine. In a real operating system this is not a good thing because either interrupts are masked (and so it won't work like a simple function call), or you will be recursively entering the kernel (which causes all sorts of concurrency problems and is the reason that the interrupts are masked in the first place. Testing: 20/100 In this section you should have proved that your implementation was correct. You should have had a couple of test programs that tested your implementation. Each test program should have been documented in the Test Documentation section of the readme file. For each test program, you should have: 1. Given the name of the test program 2. Described what the test program did when it ran 3. Described what features of the implementation were tested by the test program. You were also expected to have MEANINGFUL debug.Report output in your code, so that it was easy to see that things were working. You should have provided COMMENTED debug output that proved that your implementation was working correctly. This could have been in a separate file or in the Readme file itself. If it was in the readme file, then you should have cut out irrelevant or redundant output. Style/Presentation: 10/100 You lost marks here if your code was sloppy, or your readme file was not such a good read.