Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

1. Design and implement %u201Clock%u201D and %u201Ccondition%u201D variables. Yo

ID: 3538187 • Letter: 1

Question

1. Design and implement %u201Clock%u201D and %u201Ccondition%u201D variables. You may either use semaphore as a building block, or you may use more primitive thread routines. When you write the description of your implementation, explain and justify your design. The skeleton code (pseudo code) below is for illustration purpose only (it is incomplete and may contain errors; correct it by yourself). You can provide your own solution without using any code structure in the skeleton code as well.

2. Implement producer/consumer communication through a bounded buffer, using %u201Clock%u201D and %u201Ccondition%u201D variables. The producer places characters from the string ''Hello world'' into the buffer one character at a time; it must wait if the buffer is full. The consumer pulls characters out of the buffer one at a time and prints them to the screen; it must wait if the buffer is empty. Test your solution with a multi-character buffer and (1) with one producer and multiple consumers (2) with multiple producers and one consumer (3) with multiple producers and multiple consumers. Of course, with multiple producers or consumers, the output display will be interleaved; the point here is to illustrate the concept.

3. Department Of Transportation application: You have been hired by Department Of Transportation to synchronize traffic over a narrow light-duty bridge on a public highway. Traffic may only cross the bridge in one direction at a time, and if there are ever more than 3 vehicles on the bridge at one time, it will collapse under their weight. In this system, each car is represented by one thread, which executes the procedure OneVehicle when it arrives at the bridge:

OneVehicle(int direc)

{

ArriveBridge(direc);

CrossBridge(direc);

ExitBridge(direc);

}

In the code above, direc is either 0 or 1; it gives the direction in which the vehicle will cross the bridge.

(a) Write the procedures ArriveBridge and ExitBridge (the CrossBridge procedure should just print out a debug message), using lock and condition variables. ArriveBridge must not return until it is safe for the car to cross the bridge in the given direction (it must guarantee that there will be no head-on collisions or bridge collapses). ExitBridge is called to indicate that the caller has finished crossing the bridge; ExitBridge should take steps to let additional cars cross the bridge. This is a lightly-traveled rural bridge, so you do not need to guarantee fairness or freedom from starvation.

(b) In your solution, if a car arrives while traffic is currently moving in its direction of travel across the bridge, but there is another car already waiting to cross in the opposite direction, will the new arrival cross before the car waiting on the other side, after the car on the other side, or is it impossible to say? Explain briefly.

Explanation / Answer

documentstyle[11pt]{article} egin{document} egin{flushleft} {Large f CS-230 Programming Assignment #1} \ space*{0.2in} Due date: Monday, November 1, 1993 end{flushleft} egin{description} item{1.} Implement locks. You may either use semaphores as a building block, or you may use more primitive thread routines (such as Thread::Sleep). We have provided the public interface to locks and condition variables in synch.h. You need to define the private data and implement the interface. A lock is a variable that handles the operations Acquire() and Release(). When lock->Acquire() is executed and the lock is free, the lock state is simply set to busy and the function returns. If the lock is busy, then the thread calling Acquire() blocks until the lock is free. When lock->Release() is called and the lock is free, the function simply returns. If the lock is busy then it is set to free and a process blocked on the lock is made ready. If the lock is busy and not held by the thread doing the Release(), the function simply returns. item{2.} Implement producer/consumer communication through a bounded buffer using locks. The bounded buffer should be an explicit data-structure ({it i.e.}, class) that handles the operations Put(char) and Take() (and any others you think necessary). Your solution should include no busy waiting. The producer places characters from the string "Hello world" into the buffer one character at a time using Put; it must wait if the buffer is full. The consumer pulls characters out of the buffer one at a time using Take and prints them to the screen; it must wait if the buffer is empty. Test your solution with a buffer that holds more than one character at a time, with long messages, and with multiple producers and consumers. end{description} end{document}