# Lab 5: Solution with one mutex?

In the solution we present in class, we use two mutex variables. Many of the solutions submitted use one mutex only. A question raised during discussion with a student whether any solution with one mutex is wrong.

I will post some of the solutions submitted by you, and let you take a look and discuss. I think debugging threads is not easy and is a skill that comes with experience. So hopefully this little exercise will serve as a practice for you.

First, I will start off with the correct solution (labelled A) using two mutex variables. The mutex s ensures that only one savage waits at one time.

```VERSION A

mutex s, m
cond filled, empty

savage:
while (true)
lock(s)
lock(m)
if (pot is empty)
signal(empty)
wait(filled, m)
eat()
unlock(m)
unlock(s)

cook:
while (true)
lock(m)
if (pot is not empty)
wait(empty, m)
cook()
signal(filled)
unlock(m)```

Before we move on to implementations that uses one mutex, here is a slight variable of the above. Here, locking and unlocking of m is done inside the if statement. Is it correct?

```VERSION B

mutex s, m
cond filled, empty

savage:
while (true)
lock(s)
if (pot is empty)
lock(m)  < --
signal(empty)
wait(filled, m)
unlock(m) <--
eat()
unlock(s)

cook:
while (true)
lock(m)
if (pot is not empty)
wait(empty, m)
cook()
signal(filled)
unlock(m)```

Now, here are the four versions of solutions that uses only one mutex.

Version C removes the use of mutex s.

```VERSION C

mutex m
cond filled, empty

savage:
while (true)
lock(m)
if (pot is empty)
signal(empty)
wait(filled, m)
eat()
unlock(m)

cook:
while (true)
lock(m)
if (pot is not empty)
wait(empty, m)
cook()
signal(filled)
unlock(m)
```

```VERSION D

mutex m
cond filled, empty

savage:
while (true)
lock(m)
if (pot is empty)
signal(empty)
wait(filled, m)
eat()
unlock(m)

cook:
while (true)
lock(m)
if (pot is not empty)
wait(empty, m)
cook()
unlock(m)
```

Version E added a signal(filled) after eat() to VERSION C.

```VERSION E

mutex m
cond filled, empty

savage:
while (true)
lock(m)
if (pot is empty)
signal(empty)
wait(filled, m)
eat()
signal(filled) < --
unlock(m)

cook:
while (true)
lock(m)
if (pot is not empty)
wait(empty, m)
cook()
signal(filled)
unlock(m)
```

Version F changes the if statement to while statement.

```VERSION F

mutex m
cond filled, empty

savage:
while (true)
lock(m)
while  (pot is empty)   < --
signal(empty)
wait(filled, m)
eat()
signal(filled)
unlock(m)

cook:
while (true)
lock(m)
if (pot is not empty)
wait(empty, m)
cook()
signal(filled)
unlock(m)
```