Dining Philosophers Problem solved by the help of mutexes

Dependencies:   mbed-rtos mbed

## main.cpp

Committer:
icserny
Date:
2016-02-10
Revision:
0:1424c0020312

### File content as of revision 0:1424c0020312:

```/** 10_rtos_dpp_mutex
* The dining philosophers problem is invented by E. W. Dijkstra.
* Imagine that five philosophers sitting around a round table with five chairs,
* who spend their lives alternating between thinking and eating
* from a large bowl of rice at random intervals.
* However, there are only five chopsticks available at the right hand and
* left hand of each philosopher. Each philosopher thinks. When he gets hungry,
* he picks up the two chopsticks that are closest to him. If a philosopher can pick
* up both chopsticks, he eats for a while. After a philosopher finishes eating,
* he puts down the chopsticks and starts to think again.
*
* Since the chopsticks are shared between the philosophers, access to the chopsticks
* must be protected, but if care isn't taken, concurrency problems arise. Most notably,
* starvation via deadlock can occur: if each philosopher picks up a chopstick as soon
* as it is available and waits indefinitely for the other, eventually they will all end
* up holding only one chopstick with no chance of acquiring another.
*
* In this solution we instruct our philosophers to cooperate: to put down the
* acquired chopstick, if the second is not available, and wait for a (short) random interval.
* This is the same techniqe used by the network cards when they detected packet collision.
*
* The five chopsticks are represented by five mutexes.
* The philosophers are represented as threads.
*
* Hardware requirements:
*  - FRDM-KL25Z board
*/
#include "mbed.h"
#include "rtos.h"

Mutex stdio_mutex;
Mutex chopstick[5];                                 //Array of mutexes representing the 5 chopsticks

void notify(int num, int state)
{
stdio_mutex.lock();
if(state) {
printf("Philospher %d is EATING \n\r", num);
}
else {
printf("Philospher %d is thinking \n\r", num);
}
stdio_mutex.unlock();
}

void philosopher(void const *args)
{
while (true) {
if(chopstick[(int)args-1].trylock()) {
if(chopstick[(int)args%5].trylock()) {
notify((int)args,1);                //Start EATING
Thread::wait(1000+rand()%1000);
chopstick[(int)args%5].unlock();      //Release chopsticks
chopstick[(int)args-1].unlock();
notify((int)args,0);                //Start Thinking
Thread::wait(2000+rand()%2000);     //Get's hungry after this time...
}
else {
chopstick[(int)args-1].unlock();
Thread::wait(100+rand()%100);       //Wait for random time if failed
}
}
else {
Thread::wait(100+rand()%100);           //Wait for random time if failed
}

}
}

int main()
{
Thread t2(philosopher, (void *)2U);
Thread t3(philosopher, (void *)3U);
Thread t4(philosopher, (void *)4U);
Thread t5(philosopher, (void *)5U);
philosopher((void *)1U);
}

```