Today : Sat, 25 May 13 .

Question 1: Condition variables

A file is to be shared among different threads, each of which has a unique number. The file can be accessed simultaneously by several threads, subject to a single constraint: the sum of the numbers of the threads cannot exceed n, where n is a constant. Write code using locks and condition variables to coordinate access to the file. The interface to the file should be:

```  void access_file(void)
void release_file(void)
```

The `access_file()` function should block until the file is available, and the release_file() function should wake up any necessary waiting threads.

Question 2: Semaphores

Please write code so solve this problem using semaphores. You can rely on three functions: `sem_t sem_init(int value)` initializes a semaphore to the specified value. `sem_wait(sem_t sem)` waits for a semaphore, and `sem_signal(sem_t sem)` signals a semaphore.

A barbershop has 3 chairs for waiting customers and a single barber chair. Customers enter the barbershop. If the waiting chairs are full, the customer leaves. Otherwise, the customer sits in a waiting chair.

The barber sleeps (waits) when there are no waiting customers. When a customer arrives and the barber is sleeping, the customer wakes the barber and moves to the barber chair, where the barber cuts her hair. When the haircut is over, the customer leaves. If there are waiting customers, one of them moves to the barber chair. Otherwise, the barber waits for more customers.

Write a program to implement this system. The barber should be implemented as a `while()` loop, waiting for customers and then calling a `cut_hair()` function when a customer is in the barber chair. The customer should call `enter_shop()`, which should either return, if the chairs or full, or make the customer wait until her haircut is complete.

It may be helpful to think about this as a producer/consumer problem: who is the producer, who is the consumer? What is the buffer?

Question 3: OS Races

Describe two OS data structures (such as a TCB or page table), in which race conditions are possible. Explain how a race condition can occur.

Question 4: Locking

One problem with locks is that they can reduce performance: if all threads are waiting for a lock, only one thread can execute. A common solution to this is fine-grained locking, or using separate locks for different variables. When a small number of locks are used, the usage is called coarse-grained locking.
Consider a hash table that is created out of an array of buckets, and each bucket contains a linked list of items within that bucket. Items are found by hashing a key to one of the buckets and then searching the list within the bucket.

1. Describe a coarse-grained locking approach to preventing race conditions for the hash table. How many locks do you need, when do you acquire/release each lock?
2. Describe a fined-grained locking approach to preventing race conditions for the hash table. This approach should allow multiple threads to access the table simultaneously when they do not cause race conditions.
• Describe when simultaneous access is safe and unsafe
• Describe when you acquire/release locks and which lock you acquire/release