CS560 Midterm Exam - March 17, 2005

Jim Plank


Question 1

Part 1: Explain in detail how a three-level multi-level feedback queue works, and why it is a good scheduling algorithm. Be thorough, discussing all implications of the scheduling algorithm (think about the class discussion and simulation).

Part 2: Suppose we have an I/O-bound job that has CPU bursts that are 400 microseconds each. Our time quantum is one millisecond. Can you explain why this job could have performance issues if our multilevel feedback queue did not have the second-level queue?


Question 2

Of the four transaction schedules below, which ones are serializable? Which ones could result from a two-phase locking protocol? Assume that in order to read or write an item, the lock for that item must be held. R(A) stands for read data item A. W(A) stands for write data item A. T1 stands for Transaction #1.

Schedule A
T1T2
W(A)
R(A)
R(A)
W(C)
R(C)
R(D)
R(D)
Schedule B
T1T2
R(A)
W(C)
R(D)
W(D)
W(C)
R(C)
Schedule C
T1T2
R(A)
W(C)
R(C)
W(D)
R(D)
Schedule D
T1T2
R(A)
W(D)
R(C)
R(E)
W(D)
W(E)


Question 3

A student comes to you, because his kthreads implementation is generating a segmentation violation. The segfault occurs between lines 73 and 94 of kt.c (attached at the end of the exam). Why is the segfault occuring, and how can you fix it? (Note, I only changed a few lines of kt.c.)

Question 4

Define a safe state, and how it is used in deadlock avoidance.




Question 5

In any thread system, one has to decide whether to free a thread's stack when the thread exits, or at a later time. Given that stacks take up a non-negligible amount of memory, give a good reason why you would not free a thread's stack when it exits.

Question 6

You are in a non-preemptive, multithreaded system. Your job is going to be to write two procedures:

The list rlist is a dllist whose vals are pointers to the type Resource, which is a struct. The only field of that struct about which you need to care is the field inuse, which is an integer. The inuse field is 1 when the resource has been locked, and 0 when it is unlocked. You lock a resource by calling lock_resource(Resource *r), and you unlock a resource by calling unlock_resource(Resource *r). You should not set inuse -- that will be done by lock_resource() and unlock_resource(). However, you will want to read its value.

Your job is to implement lock_resources() and unlock_resources() so that they are guaranteed not to deadlock. You must ensure this by preventing "Hold and Wait." You may use any global variables that you want, and you may assume that both semaphores and locks/condition variables are part of your thread system. Just make up their syntax -- semaphores should have a new_sem() routine, plus P() and V().

Do not solve this by preventing "Circular Wait." If you do, you will not receive credit.

Hint: This is slightly subtle. If you block when you call lock_resources(), you have to be unblocked somehow. Think about it.

Your solution does not have to be starvation-free.