Please work out the pre-lab problems before your next lab section. The GSI/IAs will go over these problems during the lab section.

[pre-lab and in-lab] 1. Luxury box access

The Rose Bowl rents out its luxury box to fans. To prevent fights between fans of opposing teams, the management enforces a rule that all fans in the luxury box must be fans of the same team. Assume the luxury box has unlimited seats.

Your task is to write a program which controls access to the luxury box, using the Mesa monitors that are provided by the Project 1 thread library. You will write the following procedures: big10_fan_enters(), big10_fan_leaves(), pac12_fan_enters(), pac12_fan_leaves().

[pre-lab] A. Write the above functions to control access to the luxury box. For this solution, you need not be concerned about starvation, i.e., it's ok if a person waits indefinitely (but they must be allowed to enter if the luxury box is unoccupied).

[in-lab] B. Modify your solution to prevent starvation. In other words, ensure that a person will not wait indefinitely to enter, assuming that each person already in the luxury box stays there for a finite time period.

We will try to ensure fairness using a variable called TURN. TURN can be set to either BIG10 or PAC12. Write a solution that uses the TURN variable to alternate priorities between BIG 10 and PAC 12 fans when both groups are waiting. For example, if there are BIG 10 fans in the luxury box and PAC 12 fans waiting for the luxury box, then a BIG 10 fan arrives, the BIG 10 fan should only be allowed in if TURN = BIG10. Flip the TURN variable when appropriate.

Notice that we can change the TURN variable in either the big10_leaves() function, or the big10_enters() function.

  1. Describe the fairness policy enforced if we change the TURN variable in big10_enters().
  2. Describe the fairness policy enforced if we change the TURN variable in big10_leaves().
  3. Do either of these actually prevent starvation?
We want a policy that maximizes concurrency while not allowing for starvation. What fairness policy do we actually want? What would it take to implement this?

[pre-lab] 2. Locks

Assume n threads are accessing m independent shared objects (e.g., shared variables). How many locks are required to provide maximum concurrency within the threads? Does more concurrency imply better performance?

[pre-lab] 3. File access

Several threads are accessing a file. Each thread has a a unique priority number. The file can be accessed simultaneously by several threads, subject to the following constraint: the sum of all unique priority numbers of the threads currently accessing the file must be less than n.

Show how to use monitors to coordinate access to the file.

[pre-lab] 4. Barriers

(This problem has optional background material. The background reading tries to give you a sense of how you might find parallelism and use monitors in a real world problem, and attempts to motivate the usefulness of barriers. If you'd like to read the background material, click here. It is not necessary to understand the background material to do the problem.)

A barrier is a tool that provides a way for various threads to synchronize their progress. Threads "check in" or wait at a barrier and are only allowed to proceed past the barrier when a certain number of threads have "checked in" to the barrier. This tool allows a program to run phases in parallel (particularly useful in matrix operations).

Your job is to implement barriers using monitors. Implement the constructor and wait function adding private variables as needed.

class Barrier {
  //Add your private member variables

  /* Constructs a new barrier that will allow number_of_threads
     threads to check in. */
  Barrier(int number_of_threads);

  /* Called by a thread checking in to the barrier. Should return
     true if the thread was the last thread to check in (in POSIX threads
     lingo, the "serial thread") and false otherwise. This function should
     block until all threads have checked in. */
  bool wait();

  /* Delete copy constructor and copy assignment operators */
  Barrier(const Barrier&) = delete;
  Barrier& operator=(const Barrier&) = delete;
  Barrier(Barrier&&) = delete;
  Barrier& operator=(Barrier&&) = delete;