# Operating Systems

Start Lecture #12

### 2.3.6 Mutexes

Remark: Whereas we use the term semaphore to mean binary semaphore and explicitly say generalized or counting semaphore for the positive integer version, Tanenbaum uses semaphore for the positive integer solution and mutex for the binary version. Also, as indicated above, for Tanenbaum semaphore/mutex implies a blocking primitive; whereas I use binary/counting semaphore for both busy-waiting and blocking implementations. Finally, remember that in this course our only solutions are busy-waiting.
My Terminology
Busy waitblock/switch
critical(binary) semaphore(binary) semaphore
semi-criticalcounting semaphorecounting semaphore
Tanenbaum's Terminology
Busy waitblock/switch
criticalenter/leave regionmutex
semi-criticalno namesemaphore

### 2.3.9 Barriers

You can find some information on barriers in my lecture notes for a follow-on course (see in particular lecture number 16).

## 2.5 Classical IPC Problems

### 2.5.0 The Producer-Consumer (or Bounded Buffer) Problem

We did this previously.

### 2.5.1 The Dining Philosophers Problem

A classical problem from Dijkstra

• 5 philosophers sitting at a round table
• Each has a plate of spaghetti
• There is a fork between each two
• Need two forks to eat

What algorithm do you use for access to the shared resource (the forks)?

• The obvious solution (pick up right; pick up left) deadlocks.
• Big lock around everything serializes.
• Good code in the book.

The purpose of mentioning the Dining Philosophers problem without giving the solution is to give a feel of what coordination problems are like. The book gives others as well. The solutions would be covered in a sequel course. If you are interested look, for example here.

Homework: 45 and 46 (these have short answers but are not easy). Note that the second problem refers to fig. 2-20, which is incorrect. It should be fig 2-46.

### 2.5.2 The Readers and Writers Problem

As in the producer-consumer problem we have two classes of processes.

• Readers, which can work concurrently.
• Writers, which need exclusive access.

The problem is to

1. prevent 2 writers from being concurrent.
2. prevent a reader and a writer from being concurrent.
3. permit readers to be concurrent when no writer is active.
4. (perhaps) insure fairness (e.g., freedom from starvation).

Variants

Solutions to the readers-writers problem are quite useful in multiprocessor operating systems and database systems. The easy way out is to treat all processes as writers in which case the problem reduces to mutual exclusion (P and V). The disadvantage of the easy way out is that you give up reader concurrency. Again for more information see the web page referenced above.

## 2.5A Critical Sections versus Database Transactions

Critical Sections have a form of atomicity, in some ways similar to transactions. But there is a key difference: With critical sections you have certain blocks of code, say A, B, and C, that are mutually exclusive (i.e., are atomic with respect to each other) and other blocks, say D and E, that are mutually exclusive; but blocks from different critical sections, say A and D, are not mutually exclusive.

The day after giving this lecture in 2006-07-spring, I found a modern reference to the same question. The quote below is from Subtleties of Transactional Memory Atomicity Semantics by Blundell, Lewis, and Martin in Computer Architecture Letters (volume 5, number 2, July-Dec. 2006, pp. 65-66). As mentioned above, busy-waiting (binary) semaphores are often called locks (or spin locks).

... conversion (of a critical section to a transaction) broadens the scope of atomicity, thus changing the program's semantics: a critical section that was previously atomic only with respect to other critical sections guarded by the same lock is now atomic with respect to all other critical sections.

## 2.5B: Summary of 2.3 and 2.5

We began with a subtle bug (wrong answer for x++ and x--) and used it to motivate the Critical Section Problem for which we provided a (software) solution.

We then defined (binary) Semaphores and showed that a Semaphore easily solves the critical section problem and doesn't require knowledge of how many processes are competing for the critical section. We gave an implementation using Test-and-Set.

We then gave an operational definition of Semaphore (which is not an implementation) and morphed this definition to obtain a Counting (or Generalized) Semaphore, for which we gave NO implementation. I asserted that a counting semaphore can be implemented using 2 binary semaphores and gave a reference.

We defined the Producer-Consumer (or Bounded Buffer) Problem and showed that it can be solved using counting semaphores (and binary semaphores, which are a special case).

Finally we briefly discussed some classical problems, but did not give (full) solutions.

Skipped.

## 2.7 Summary

Remark: Deadlocks are closely related to process management so belong here, right after chapter 2. It was here in 2e. A goal of 3e is to make sure that the basic material gets covered in one semester. But I know we will do the first 6 chapters so there is no need for us to postpone the study of deadlock.

A deadlock occurs when every member of a set of processes is waiting for an event that can only be caused by a member of the set.

Often the event waited for is the release of a resource.

In the automotive world deadlocks are called gridlocks.

• The processes are the cars.
• The resources are the spaces occupied by the cars

For a computer science example consider two processes A and B that each want to print a file currently on a CD-ROM Drive.

1. A has obtained ownership of the printer and will release it after getting the CD Drive and printing one file.
2. B has obtained ownership of the CD drive and will release it after getting the printer and printing one file.
3. A tries to get ownership of the drive, but is told to wait for B to release it.
4. B tries to get ownership of the printer, but is told to wait for A to release it.

## 6.1 Resources

A resource is an object granted to a process.

### 6.1.1 Preemptable and Nonpreemptable Resources

Resources come in two types

1. Preemptable, meaning that the resource can be taken away from its current owner (and given back later). An example is memory.
2. Non-preemptable, meaning that the resource cannot be taken away. An example is a printer.

The interesting issues arise with non-preemptable resources so those are the ones we study.

The life history of a resource is a sequence of

1. Request
2. Allocate
3. Use
4. Release

Processes request the resource, use the resource, and release the resource. The allocate decisions are made by the system and we will study policies used to make these decisions.

### 6.1.2 Resource Acquisition

A simple example of the trouble you can get into.

• Two resources and two processes.
• Each process wants both resources.
• Use a semaphore for each. Call them S and T.
• If both processes execute
P(S); P(T); --- V(T); V(S)
all is well.
• But if one executes instead
P(T); P(S); -- V(S); V(T)
disaster! This was the printer/CD example just above.

Recall from the semaphore/critical-section treatment last chapter, that it is easy to cause trouble if a process dies or stays forever inside its critical section. We assume processes do not do this. Similarly, we assume that no process retains a resource forever. It may obtain the resource an unbounded number of times (i.e. it can have a loop forever with a resource request inside), but each time it gets the resource, it must release it eventually.

Definition: A deadlock occurs when a every member of a set of processes is waiting for an event that can only be caused by a member of the set.

Often the event waited for is the release of a resource.

### 6.2.1 (Necessary) Conditions for Deadlock

The following four conditions (Coffman; Havender) are necessary but not sufficient for deadlock. Repeat: They are not sufficient.

1. Mutual exclusion: A resource can be assigned to at most one process at a time (no sharing).
2. Hold and wait: A processing holding a resource is permitted to request another.
3. No preemption: A process must release its resources; they cannot be taken away.
4. Circular wait: There must be a chain of processes such that each member of the chain is waiting for a resource held by the next member of the chain.

One can say If you want a deadlock, you must have these four conditions.. But of course you don't actually want a deadlock, so you would more likely say If you want to prevent deadlock, you need only violate one or more of these four conditions..

The first three are static characteristics of the system and resources. That is, for a given system with a fixed set of resources, the first three conditions are either always true or always false: They don't change with time. The truth or falsehood of the last condition does indeed change with time as the resources are requested/allocated/released.

On the right are several examples of a Resource Allocation Graph, also called a Reusable Resource Graph.

• The processes are circles.
• The resources are squares.
• An arc (directed line) from a process P to a resource R signifies that process P has requested (but not yet been allocated) resource R.
• An arc from a resource R to a process P indicates that process P has been allocated resource R.

Homework: 5.

Consider two concurrent processes P1 and P2 whose programs are.

```    P1                   P2
request R1           request R2
request R2           request R1
release R2           release R1
release R1           release R2
```

On the board draw the resource allocation graph for various possible executions of the processes, indicating when deadlock occurs and when deadlock is no longer avoidable.

There are four strategies used for dealing with deadlocks.

1. Ignore the problem
2. Detect deadlocks and recover from them
3. Prevent deadlocks by violating one of the 4 necessary conditions.
4. Avoid deadlocks by carefully deciding when to allocate resources.