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

Committer:
icserny
Date:
Wed Feb 10 12:43:09 2016 +0000
Revision:
0:15e98ba559c1
First version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
icserny 0:15e98ba559c1 1 /** 10_rtos_semaphore
icserny 0:15e98ba559c1 2 * In this example three threads are competing for two
icserny 0:15e98ba559c1 3 * resources. The number of free resources is managed in a semaphore
icserny 0:15e98ba559c1 4 * while the indiviual resource accesses are protected by 1-1 mutex.
icserny 0:15e98ba559c1 5 * The RGB LED shows the waitings state of tasks accessing no resource.
icserny 0:15e98ba559c1 6 *
icserny 0:15e98ba559c1 7 * Hardware requirements:
icserny 0:15e98ba559c1 8 * - FRDM-KL25Z board
icserny 0:15e98ba559c1 9 */
icserny 0:15e98ba559c1 10
icserny 0:15e98ba559c1 11 #include "mbed.h"
icserny 0:15e98ba559c1 12 #include "rtos.h"
icserny 0:15e98ba559c1 13
icserny 0:15e98ba559c1 14 Semaphore sem(2); //manges two tokens
icserny 0:15e98ba559c1 15 Mutex m1, m2; //two mutexes for two resources
icserny 0:15e98ba559c1 16 Mutex stdio_mutex; //Control shared access to printf
icserny 0:15e98ba559c1 17 DigitalOut led1(LED1); //Red LED
icserny 0:15e98ba559c1 18 DigitalOut led2(LED2); //Green LED
icserny 0:15e98ba559c1 19 DigitalOut led3(LED3); //Blue LED
icserny 0:15e98ba559c1 20 DigitalOut ledarray[]= {led1,led2,led3}; //Just needed for indexing the individual objects...
icserny 0:15e98ba559c1 21 Timer mytime;
icserny 0:15e98ba559c1 22
icserny 0:15e98ba559c1 23 void notify(int tid, int res) {
icserny 0:15e98ba559c1 24 stdio_mutex.lock();
icserny 0:15e98ba559c1 25 if(res > 0) {
icserny 0:15e98ba559c1 26 printf("Task %d: acquired << resource %d. at %8.1f\n\r", tid, res, mytime.read());
icserny 0:15e98ba559c1 27 } else {
icserny 0:15e98ba559c1 28 printf("Task %d: released >> resource %d. at %8.1f\n\r", tid, -res, mytime.read());
icserny 0:15e98ba559c1 29 }
icserny 0:15e98ba559c1 30 stdio_mutex.unlock();
icserny 0:15e98ba559c1 31 }
icserny 0:15e98ba559c1 32
icserny 0:15e98ba559c1 33 void mythread(void const* args) {
icserny 0:15e98ba559c1 34 while (true) {
icserny 0:15e98ba559c1 35 Thread::wait(500+rand()%500);
icserny 0:15e98ba559c1 36 ledarray[(int)args-1]=0; //LEDx on
icserny 0:15e98ba559c1 37 sem.wait(); //Wait for token
icserny 0:15e98ba559c1 38 if(m1.trylock()) { //Try to lock mutex #1
icserny 0:15e98ba559c1 39 ledarray[(int)args-1]=1; //LEDx off
icserny 0:15e98ba559c1 40 notify((int)args,1);
icserny 0:15e98ba559c1 41 Thread::wait(1000+rand()%500);
icserny 0:15e98ba559c1 42 notify((int)args,-1);
icserny 0:15e98ba559c1 43 m1.unlock();
icserny 0:15e98ba559c1 44 } else {
icserny 0:15e98ba559c1 45 m2.lock(); //Wait for mutex #2
icserny 0:15e98ba559c1 46 ledarray[(int)args-1]=1; //LEDx off
icserny 0:15e98ba559c1 47 notify((int)args,2);
icserny 0:15e98ba559c1 48 Thread::wait(1000+rand()%500);
icserny 0:15e98ba559c1 49 notify((int)args,-2);
icserny 0:15e98ba559c1 50 m2.unlock();
icserny 0:15e98ba559c1 51 }
icserny 0:15e98ba559c1 52 sem.release(); //Release token
icserny 0:15e98ba559c1 53 }
icserny 0:15e98ba559c1 54 }
icserny 0:15e98ba559c1 55
icserny 0:15e98ba559c1 56 int main (void) {
icserny 0:15e98ba559c1 57 led1 = 1;
icserny 0:15e98ba559c1 58 led2 = 1;
icserny 0:15e98ba559c1 59 led3 = 1; //Switch off all LEDs
icserny 0:15e98ba559c1 60 mytime.start(); //Start timer
icserny 0:15e98ba559c1 61 Thread t2(mythread,(void *)2U); //Define and run thread2
icserny 0:15e98ba559c1 62 Thread t3(mythread,(void *)3U); //Define and run thread3
icserny 0:15e98ba559c1 63 mythread((void const*)1U); //Run thread1
icserny 0:15e98ba559c1 64 }