Dining Philosophers Problem solved by the help of mutexes

Dependencies:   mbed-rtos mbed

Revision:
0:1424c0020312
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Feb 10 12:58:14 2016 +0000
@@ -0,0 +1,77 @@
+/** 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);
+}