





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
Material Type: Exam; Class: Intro Oper System; Subject: Electrical Engineering And Computer Science; University: University of Michigan - Ann Arbor; Term: Fall 1998;
Typology: Exams
1 / 9
This page cannot be seen from the preview
Don't miss anything!






You will have 80 minutes to work on this exam, which is closed book. There are 4 problems on 9 pages.
Read the entire exam through before you begin working. Work on those problems you find easiest first. Read each question carefully, and note all that is required of you. Keep your answers clear and concise, and carefully state all of your assumptions.
You are to abide by the University of Michigan/Engineering honor code. Please sign below to indicate that you have abided by the honor code on this exam.
Honor code pledge: I have neither given nor received aid on this exam.
Signature:___________________________
1. Analyzing a Concurrent Program (approx. 20 minutes)
The following is an implementation of an atomic transfer function. transfer should atom- ically dequeue an item from one queue and enqueue it on another. By atomically, we mean that there must be no interval of time during which an external thread can determine that an item has been removed from one queue but not yet placed on another (assuming the external thread locks a queue before examining it). transfer must complete in a finite amount of time, and must allow multiple transfers between unrelated queues to happen in parallel. You may assume the following:
- queue1 and queue2 never refer to the same queue. - queue1 always has an item to dequeue (so dequeue(queue1) succeeds). - dequeue, enqueue, threadLock, and threadUnlock are all written correctly. - threadLock is fair. That is, lock requests are granted in the order of the calls.
State whether the implementation (i) works, (ii) doesn’t work, or (iii) sometimes works and sometimes doesn’t work.
- If you claim it works, present your reasoning about how you came to this conclusion. - If you claim it doesn’t work (or only works sometimes), describe the circumstances that cause it not to work, and re-write transfer so it always works (and still meets all the require- ments).
struct queue {
int lockNum; /* a unique lock number per queue */ item headPtr; / pointer to the head of the queue */
};
void transfer(struct queue *queue1, struct queue *queue2) {
item thing; / the item being transferred */ threadLock(queue1->lockNum); threadLock(queue2->lockNum); thing = dequeue(queue1); enqueue(queue2, thing); threadUnlock(queue2->lockNum); threadUnlock(queue1->lockNum); }
2. Writing a Concurrent Program (approx. 20 minutes)
You have joined a software company that is writing an implementation of the Banker’s algo- rithm for the Michigan Credit Union. They have defined the global variables below. They have also written the function isDangerous(int customer, int amount), which returns 1 if letting the specified customer borrow the specified amount may allow deadlock (otherwise isDangerous returns 0). isDangerous does not modify any global variables.
int cash; /* amount of cash currently at the Credit Union */
int creditLimit[CUSTOMERS]; /* each customer’s credit limit (the maximum each customer can borrow) */
int currentBorrowed[CUSTOMERS]; /* the current amount borrowed by each customer */
Recall the general structure of a thread that uses the Banker’s algorithm: declareCreditLimit /* sets creditLimit[customer] / while (not done) { getCash(customer, amount) / borrow money against credit limit */ do work } returnAllCash(customer)
Your job is to implement the getCash and returnAllCash functions. Assume a cus- tomer never calls getCash with an amount that would cause him/her to exceed his credit limit. Use monitors (threadLock, threadUnlock, threadWait, threadSignal, and threadBroadcast) to handle synchronization. Keep your solution as simple as possible.
getCash(int customer, int amount) {
}
returnAllCash(int customer) {
}
4. Lazy Fork (approx. 20 minutes)
As discussed in class, Unix fork initializes the contents of the child’s address space by aggressively copying the contents of the parent’s address space. Your job is to speed up fork by deferring or avoiding the work of copying data between the two address spaces. Your solution should reduce the number of bytes copied as much as possible for the two common ways of using fork: running two copies of the same program, and starting a new program by using exec after fork. Other than increased speed, user processes should not notice any difference between the old and new fork. Assume that address spaces are represented by a simple page table, and that the MMU respects read/write protection bits and sets reference and dirty bits appropriately. Hint: think about sharing data between the parent and child.
Describe how to modify fork to defer or avoid copying. Be specific and concise in your answers. Note that there are 4 parts to answer (two are on the following page).
a. What is the unit of copying, and why should/can the copy not be done on a larger or smaller unit?
b. What events in the parent will trigger a copy? What events in the child will trigger a copy?