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
T1 | | T2 |
W(A) | | |
| | R(A) |
R(A) | | |
W(C) | | |
| | R(C) |
R(D) | | |
| | R(D) |
|
|
Schedule B
T1 | | T2 |
R(A) | | |
W(C) | | |
R(D) | | |
| | W(D) |
W(C) | | |
| | R(C) |
|
|
Schedule C
T1 | | T2 |
R(A) | | |
W(C) | | |
| | R(C) |
| | W(D) |
R(D) | | |
|
|
Schedule D
T1 | | T2 |
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:
- lock_resources(Dllist rlist);
- unlock_resources(Dllist rlist);
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.