Screencast 12

Every semester I lost at least one screencast due to human errors or technical problems. I thought I would get away this semester without a hitch, but alas, on the last lecture, the screencast for the last half of the lecture is lost.

So, here is the screencast for the first half of Lecture 12.

For the second half, I wrote down what I said as much as I can remember, to finish off the “ls” example. Here is the PDF file.

Lab 7: Comments

Lab 7 has been graded and posted on IVLE gradebook.  Mr. Fang graded the lab and has the following comments for you:

The average score of lab 7 is 13.7 out of 15, most of the students get a very good grade for this lab. Below are some comments on some of the common mistakes.

For question 1(b), some students think that the difference in program counter is due to the function call printf(). However, this is not the case. We can verify this by duplicating the line of printf() a few times, and observe the output.

For question 3(b), some students did not indicate the unit and some students get confuse with milliseconds (ms), microseconds (us) and nanosecond (ns).

Some of the questions require the answer to be within 500 characters, this is to encourage the students to answer only what is asked instead of putting down everything on the topic.

We received several emails about 3(c).  The right solution equation takes the form of (m+h = ..) and (m + 4h = ..) If you got this wrong, you should make sure that you understand why this is so.  I think understanding this part means that you have a good understanding of how page access/page faults work.

Lab 6: Comments

Part 1 of Lab 6 (MLFQ implementation) has been graded and the grades are available through IVLE gradebook. Hong Dai Thanh graded this lab, and he has the following comments for you.

Grading Scheme

  • mlfq_create_job: 2 marks
  • mlfq_next_job: 2 marks
  • mlfq_ready_job: 3 marks
  • mlfq_preempt_job: 3 marks

First of all, I would like to comment on the coding practice. I observed a lot of submissions that don’t initialize job->priority in mlfq_create_job, hard code number instead of using the given macro, using a “waterfall” of if statements, using features that are compiler-dependent, etc. Since this is not a software engineering module, I don’t penalize for those errors. However, you should be aware that writing program in that way will make the code very hard to modify when the specification changes.

Most of the submissions implements mlfq_create_job correctly. There are quite a number of submissions that don’t initialize job->priority. Technically, this is a programming error, since malloc doesn’t guarantee the memory allocated will be initialized to 0. However, I don’t penalize for this error.

Most of the submissions also implements mlfq_next_job correctly. If mlfq_next_job does not work correctly (e.g. only check the queue of the highest priority) then no mark will be given.

For mlfq_ready_job and mlfq_preempt_job, I observed many different implementations. The most straight-forward implementation will record the current priority in job->priority and update the job->time_left, job->max_time_quantum and enqueue the job accordingly. Some implementations do not use job->priority, and use a loop to compare the current max time quantum with the list of time quantum to derive the current priority level. Some implementations calculate the time quantum instead of taking it from the array mlfq.time_quantum (this is a bad programming practice). I give all those implementations full mark, as long as they are correct within the specification given.
Earlier I made a post about resetting the time left of the job when it moves up a level. AS an exercise, you can try doing it and compare the result. Since this is not mentioned in the lab sheet, I don’t penalize if you don’t reset the time left.

I will take off 1 mark for each error in this part. If you use a property without updating it, I will consider it an error. If you make the same error twice in two functions, it will be counted twice.

Max time quantum not updated: -1 each function
Job not properly enqueued: -1 each function
Off-by-one for mlfq_preempt_job: -0.5

The implementation of job_generator has a very low chance of generating a set of data in which a process gets demoted to the lowest priority level and stays there. Therefore, the program usually has a very high chance of producing the correct input even though it has an off-by-one error in mlfq_preempt_job.

I still see some cases of format violation. One or two cases submit a .tar file but is actually a .zip or .rar file renamed to .tar. Marks are deducted accordingly.

Lab 8: On zombies, wait() and signal()

Many students have reported problems with zombies in Lab 8.

I did not think it would be this hard to prevent zombies, so this is unintended, partly due to last minute change of platform (from Linux to Solaris), and confusion due to the skeleton code given.

I would rather you spend time handling the pipes properly (remember to close every unused ends!) than worrying about zombies.

So, here is a way to remove zombies in Lab 8.

replace the line

waitpid(pid, NULL, NULL)


for (i = 0; i < num_of_cmds; i++)
    waitpid(-1, NULL, NULL);

This line ensures that the parent will wait as many times as child processes forked before returning to the prompt.

Next, I will describe several other ways that does not work or tricky to get it to work.

One solution that you might have done is to move the waitpid() statement into the for loop. So, in effect, bush is calling fork(), wait(), fork(), wait().. The impact of this change is that, the second command in the pipeline will not start until after the first command finishes execution. This is problematic, because the first command might not exit or might wait for the second command to read from the pipe (e.g., when the pipe is full). Example of a pipe that can cause trouble for this solution is “yes | head”.

Another solution is to wait() asynchronously with signals like what you have done in Lab 4. Using signal is not strictly necessary in Lab 8 since we do not support background processes. But it is not wrong to use signal either. The problem, however, comes from the subtle different semantic of signal() on Linux and Solaris. While on Linux, once you install a signal, it is there to stay. On Solaris, however, after the signal handler is called, the signal handler is reset back to the default handler. To make the signal handler you installed persistent, you have to reinstall it again and again by calling signal() within the signal handler. So if you have used this approach, either use sigaction() or call signal() from within the signal handler to reinstall the handler.

Lecture 12: Putting Everything Together

11 November, 2011

This week, I will put most of the things that we have learnt together in CS2106 and traced through an example of what happen when you execute a command. We will also go into details of some steps that we haven’t have time to cover before.

Having a hardcopy of slides during lecture would be helpful. Be prepare to take notes during lecture.

Download Slides: PDF

What Exam Questions Would You Set?

I have set and submitted the final exam questions for CS2106, so it is now safe to have this fun exercise: what exam questions would you set for CS2106 final exam?

Thinking about this question would help you reflect upon your own knowledge and understanding of the materials.  For instance, if you put the emphasis on the right concepts, if you can synthesize new knowledge based on what you learned, etc.

An added benefit is that your peers would also be able to test how much they learned by answering your question.