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);
}