










Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Main points of this past exam are: Virtual Machine, Virtual Machine, Thread State, State Transitions, Banker’S Algorithm, Synchronization, Synchronization Primitives, Multiprocessor, Multiprocessor System, Condition Variables
Typology: Exams
1 / 18
This page cannot be seen from the preview
Don't miss anything!











hUniversity of California, Berkeley College of Engineering Computer Science Division ⎯ EECS
Fall 2006 John Kubiatowicz
October 11th, 2006 CS162: Operating Systems and Systems Programming
Your Name:
SID Number:
Discussion Section:
General Information: This is a closed book exam. You are allowed 1 page of hand-written notes (both sides). You have 3 hours to complete as much of the exam as possible. Make sure to read all of the questions first, as some of the questions are substantially more time consuming.
Write all of your answers directly on this paper. Make your answers as concise as possible. On programming questions, we will be looking for performance as well as correctness, so think through your answers carefully. If there is something about the questions that you believe is open to interpretation, please ask us about it!
Problem Possible Score
Total 100
Problem 1e[3pts]: For each of the following thread state transitions, say whether the transition is legal and how the transition occurs or why it cannot. Assume Mesa-style monitors.
1). Change from thread state BLOCKED to thread state RUNNING
NOT legal in most operating systems: running threads must be selected from the list of ready (or runnable) threads. If Hoare-style monitors are used, however, threads blocked on a lock can transition directly to RUNNING.
2). Change from thread state RUNNING to thread state BLOCKED
Legal: a running thread can become blocked when it requests a resource (disk I/O, a lock, etc), synchronizes with a join() operation, etc
3). Change from thread state RUNNABLE to thread state BLOCKED
NOT legal: a thread can only transition to BLOCKED from RUNNING. It must execute some action that causes it to block, and it cannot do this unless it is RUNNING.
Problem 1f[4pts]: Consider the Dining Lawyers problem, in which a set of lawyers sit around a table with one chopstick between each of them. Let the lawyers be numbered from 0 to n-1 and be represented by separate threads. Each lawyer executes Dine(i), where “i” is the lawyer’s number. Assume that there is an array of semaphores, Chop[i] that represents the chopstick to the left of lawyer i. These semaphores are initialized to 1.
void Dine(int i) { Chop[i].P(); /* Grab left chopstick / Chop[(i+1)%n].P(); / Grab right chopstick / EatAsMuchAsYouCan(); Chop[i].V(); / Release left chopstick / Chop[(i+1)%n].V(); / Release right chopstick */ }
This solution can deadlock. Assume that it does. List the four conditions of deadlock and explain why each of them is satisfied during the deadlock:
Problem 1g[3pt]: Pick one of the above four conditions and rewrite the code to eliminate it. Identify the condition you chose carefully and explain why your code doesn’t deadlock:
Circular wait: Several options here
void Dine(int i) { if (i==n-1) { Chop[0].P(); /* Grab right chopstick / Chop[n-1].P(); / Grab left chopstick / } else { Chop[i].P(); / Grab left chopstick / Chop[(i+1)%n].P(); / Grab right chopstick / } EatAsMuchAsYouCan(); Chop[i].V(); / Release left chopstick / Chop[(i+1)%n].V(); / Release right chopstick */ }
void Dine(int i) { if (i%2==1) { Chop[i].P(); /* Grab left chopstick / Chop[(i+1)%n].P(); / Grab right chopstick / } else { Chop[(i+1)%n].P(); / Grab right chopstick / Chop[i].P(); / Grab left chopstick / } EatAsMuchAsYouCan(); Chop[i].V(); / Release left chopstick / Chop[(i+1)%n].V(); / Release right chopstick */ }
Lock lock; //global variable shared by all threads void Dine(int i) { lock.Acquire(); Chop[i].P(); Chop[(i+1)%n].P(); Lock.Release(); EatAsMuchAsYouCan(); Chop[i].V(); Chop[(i+1)%n].V(); }
Assume that you are programming a multiprocessor system using threads. In class, we talked about two different synchronization primitives: Semaphores and Monitors.
The interface for a Semaphore is as follows: public class Semaphore { public Semaphore(int initialValue) { /* Create and return a semaphore with initial value: initialValue / … } public P() { / Call P() on the semaphore / … } public V() { / Call V() on the semaphore */ } } As we mentioned in class, a Monitor consists of a Lock and one or more Condition Variables. The interfaces for these two types of objects are as follows:
public class Lock { public class CondVar { public Lock() { public CondVar(Lock lock) { /* Create new Lock / / Creates a condition variable … associated with Lock lock. / } … } public void Acquire() { public void Wait() { / Acquire Lock / / Block on condition variable ’/ … … } } public void Release() { public void Signal() { / Release Lock / / Wake one thread (if it exists) / … … } } } public void Broadcast() { / Wake up all threads waiting on cv*/ … } } Monitors and Semaphores can be used for a variety of things. In fact, each can be implemented with the other. In this problem, we will show their equivalence.
Problem 2a[2pts]: What is the difference between Mesa and Hoare scheduling for monitors?
Mesa: signaler keeps lock and processor; waiter placed on ready queue and does not run immediately
Hoare: signal gives lock and CPU to waiter; waiter runs immediately; waiter gives lock and processor back to signaler when it exits critical section or waits again.
Problem 2b[5pts]: Show how to implement the Semaphore class using Monitors (i.e. the Lock and CondVar classes). Make sure to implement all three methods, Semaphore(), P(), and V(). None of the methods should require more than five lines. Assume that Monitors are Mesa scheduled.
public class Semaphore { Lock lock; // Every Monitor has a lock and CondVar CondVar c; Int value; // Semaphores have an integer value
public Semaphore(int initialValue) { value = initialValue; lock = new Lock(); c = new CondVar(lock);
} public P() { lock.Acquire(); while (value == 0) c.Wait(); value--; lock.Release(); } public V() { lock.Acquire(); value++; c.Signal(); lock.Release(); } } Problem 2c[3pts]: Show how to implement the Lock class using Semaphores. Make sure to implement the Lock(), Acquire(), and Release() methods. None of the methods should require more than five lines.
public class Lock { Semaphore s;
public Lock() { s = new Semaphore(1);
} public void Acquire() {
s.P();
} public void Release() {
s.V();
} }
For each of the following techniques for synchronization, assume that there are two threads competing to execute a critical section. Further, assume that:
Synchronization technique #1: Suppose each thread does the following:
Problem 3a[2pts]: Will this protect the critical section? If “yes”, explain why. If “no”, give an example interleaving that will fail to protect the critical section.
No. Thread A runs line 1, determines flag is false, and is context-switched. Then, thread B runs line 1 and also determines flag is false. Now threads A and B can both access critical section.
Problem 3b[2pts]: Assume this code protects the critical section. Is this code “fair”? Explain.
Yes. This code is symmetric so will each thread has an equal chance.
Synchronization technique #2: Suppose we have different code for each thread:
THREAD A THREAD B A1. flag_A = true; B1. flag_B = true; A2. while (flag_B == true) B2. if (flag_A == false) A3. do nothing; B3. Execute Critical Section; A4_. Execute Critical Section;_ B4_._ flag_B = false; A5. flag_A = false;
Problem 3c[2pts]: Will this protect the critical section? If “yes”, explain why. If “no”, give an example interleaving that will fail to protect the critical section.
Yes, thread A only enters the critical section when flag_B is false (this is satisfied only while thread B is executing before B1 or after B4). Thread B only enters the critical section when flag_A is false (this is satisfied only while thread A is executing before A1 or after A5).
Problem 3d[2pts]: Assume this code protects the critical section. Is this code “fair”? Explain.
No. Thread A always gets a chance to run the critical section during an execution of A1-A5. On the other hand, Thread B will be prevented from running the critical section whenever Thread A is in that region. If A and B are running in a tight loop, Thread B only gets to run the critical section if it is lucky enough to execute B2 between the execution of A5 and the next execution of A1.
Synchronization technique #3: Suppose each thread does the following:
Problem 3e[3pts]: Will this protect the critical section? If “yes”, explain why. If “no”, explain and explain how to fix it.
No. Since TestAndSet sets a memory location to 1 (true), the locked condition is indicated by the value of flag == true. Hence, the above code doesn’t wait when the lock is already taken. Hence, it doesn’t protect the critical section. To fix the code, replace TestAndSet(flag) == false with TestAndSet(flag) == true.
Problem 3f[2pts]: Assume the above code (or your fixed version). Will this code be “fair”? Explain.
Yes. This code is symmetric so will each thread has an equal chance.
Synchronization technique #4: Suppose we have different code for each thread:
THREAD A THREAD B A1. flag_A = true; B1. flag_B = true; A2. while (flag_B == true) B2. while (flag_A == true) A3. do nothing; B3. do nothing; A4. Execute Critical Section; B4. Execute Critical Section; A5. flag_A = false; B5_._ flag_B = false;
Problem 3g[3pts]: Will this protect the critical section? If “yes”, explain why. If “no”, explain and explain how to fix it. Note that this question is only about protecting the critical section!
Yes, thread A only enters the critical section when flag_B is false (this is satisfied only while thread B is executing before B1 or after B5). Thread B only enters the critical section when flag_A is false (this is satisfied only while thread A is executing before A1 or after A5).
Problem 3h[3pts]: Explain why this code (or your fixed version) would not be a particularly good mechanism for synchronizing threads A and B. (hint: imagine that threads A and B repeatedly try to acquire the critical section). After describing the problem, explain how to fix the problem by replacing the “do nothing” with no more than three lines inside each while loop above.
This is not a good mechanism, since there is a chance of deadlock occurring. Imagine that
For Thread A replace “do nothing” with “flag_A=false; yield(); flag_A=true” and for Thread B replace “do nothing” with “flag_B=false; yield(); flag_B=true”. This will prevent deadlock while retaining the critical section protection.
Problem 4e[5pts]: Here is a table of processes and their associated arrival and running times.
Process ID Arrival Time CPU Running Time Process 1 0 2 Process 2 1 6 Process 3 4 1 Process 4 7 4 Process 5 8 3
Show the scheduling order for these processes under 3 policies: First Come First Serve (FCFS), Shortest-Remaining-Time-First (SRTF), Round-Robin (RR) with timeslice quantum = 1. Assume that context switch overhead is 0 and that new processes are added to the head of the queue except for FCFS, where they are added to the tail.
Time Slot FCFS SRTF RR
0 1 1 1
1 1 1 2
2 2 2 1
3 2 2 2
4 2 3 3
5 2 2 2
6 2 2 2
7 2 2 4
8 3 2 5
9 4 5 2
10 4 5 4
11 4 5 5
12 4 4 2
13 5 4 4
14 5 4 5
15 5 4 4
Problem 4f[3pts]: For each process in each schedule above, indicate the queue wait time and completion time (otherwise known as turnaround time, TRT). Note that wait time is the total time spend waiting in queue (all the time in which the task is not running), while TRT is the total time from when the process arrives in the queue until it is completed.
Scheduler Process 1 Process 2 Process 3 Process 4 Process 5 FCFS wait 0 1 4 2 5 FCFS TRT
SRTF wait 0 2 0 5 1 SRTF TRT
RR wait 1 6 0 5 4 RR TRT 3 12 1 9 7
Problem 4g[2pts]: Assume that we could have an oracle perform the best possible scheduling to reduce average wait time. What would be the optimal average wait time, and which of the above three schedulers would come closest to optimal? Explain.
Since SRTF is optimal, we just look at the average wait time from the above table in the SRTF line: Optimal average wait time is 1.6.
Consider a multi-level memory management scheme using the following format for virtual addresses: Virtual seg # (4 bits)
Virtual Page # (8 bits)
Offset (8 bits)
Virtual addresses are translated into physical addresses of the following form:
Physical Page # (8 bits)
Offset (8 bits)
Problem 5d[4pts]: For the following Virtual Addresses, translate them into Physical Addresses. Use the Segment Table and Physical Memory table given on the next page. Segment entries point to page tables in memory. A page table consists of a series of 16 bit page table entries (PTEs). The format of a PTE is given on the next page. Briefly, the first byte of the PTE is an 8-bit physical page #, and the second byte is an 8-bit flags field with one of the following values:
0x00 (Invalid), 0x06 (Valid, RO), 0x07 (Valid, R/W).
If there is an error during translation, make sure to say what the error is. Errors can be “ bad segment error ” (undefined or invalid segment), “ segment overflow error ” (address outside range of segment), or “ access violation error ” (page invalid, or attempt to write a read only (RO) page). Two answers are given:
Virtual Addr Physical Addr Virtual Addr Physical Addr 0x10123 0x4123 0x31056 0x 0x33423 Segment overflow 0x10400 0x 0x20456 Bad Segment^ 0x00278 0x
Problem 5e[6pts]: Consider the same multi-level memory management scheme. Please return the results from the following load/store instructions. Addresses are virtual. The return value for load is an 8-bit data value or an error, while the return value for a store is either “ ok ” or an error. For errors, please specify which type of error (from the above set). Two answers are given:
Instruction Result Instruction Result Load [0x30115] 0x57 Store [0x00310] Ok Store [0x30116] Access violation Load [0x31202] 0x Load [0x51015] Bad Segment Store [0x10231] Access Violation Load [0x00115] Access Violation^ Load [0x12345] Segment Overflow
Virtual seg # (4 bits)
Virtual Page # (8 bits)
Offset (8 bits)
First Byte Second Byte
Physical Page Number
0x00 = Invalid 0x06 = Valid, RO 0x07 = Valid, R/W