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

main.cpp

Committer:
icserny
Date:
2016-02-10
Revision:
0:15e98ba559c1

File content as of revision 0:15e98ba559c1:

/** 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
}