In this example three threads are competing for two resources. The number of free resources is managed in a semaphore while the indiviual resource accesses are protected by 1-1 mutex. The RGB LED shows the waitings state of tasks accessing no resource.

Dependencies:   mbed-rtos mbed

Revision:
0:15e98ba559c1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Feb 10 12:43:09 2016 +0000
@@ -0,0 +1,64 @@
+/** 10_rtos_semaphore
+ * In this example three threads are competing for two
+ * resources. The number of free resources is managed in a semaphore
+ * while the indiviual resource accesses are protected by 1-1 mutex.
+ * The RGB LED shows the waitings state of tasks accessing no resource.
+ *
+ * Hardware requirements:
+ *  - FRDM-KL25Z board
+ */
+
+#include "mbed.h"
+#include "rtos.h"
+
+Semaphore sem(2);                           //manges two tokens
+Mutex m1, m2;                               //two mutexes for two resources
+Mutex stdio_mutex;                          //Control shared access to printf
+DigitalOut led1(LED1);                      //Red LED
+DigitalOut led2(LED2);                      //Green LED
+DigitalOut led3(LED3);                      //Blue LED
+DigitalOut ledarray[]= {led1,led2,led3};    //Just needed for indexing the individual objects...
+Timer mytime;
+
+void notify(int tid, int res) {
+    stdio_mutex.lock();
+    if(res > 0) {
+        printf("Task %d: acquired << resource %d. at %8.1f\n\r", tid, res, mytime.read());
+    } else {
+        printf("Task %d: released >> resource %d. at %8.1f\n\r", tid, -res, mytime.read());
+    }
+    stdio_mutex.unlock();
+}
+
+void mythread(void const* args) {
+    while (true) {
+        Thread::wait(500+rand()%500);
+        ledarray[(int)args-1]=0;            //LEDx on
+        sem.wait();                         //Wait for token
+        if(m1.trylock()) {                  //Try to lock mutex #1
+            ledarray[(int)args-1]=1;        //LEDx off
+            notify((int)args,1);
+            Thread::wait(1000+rand()%500);
+            notify((int)args,-1);
+            m1.unlock();
+        } else {
+            m2.lock();                      //Wait for mutex #2
+            ledarray[(int)args-1]=1;        //LEDx off
+            notify((int)args,2);
+            Thread::wait(1000+rand()%500);
+            notify((int)args,-2);
+            m2.unlock();
+        }
+        sem.release();                      //Release token
+    }
+}
+
+int main (void) {
+    led1 = 1;
+    led2 = 1;
+    led3 = 1;                               //Switch off all LEDs
+    mytime.start();                         //Start timer
+    Thread t2(mythread,(void *)2U);         //Define and run thread2
+    Thread t3(mythread,(void *)3U);         //Define and run thread3
+    mythread((void const*)1U);              //Run thread1
+}