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.
main.cpp@0:15e98ba559c1, 2016-02-10 (annotated)
- Committer:
- icserny
- Date:
- Wed Feb 10 12:43:09 2016 +0000
- Revision:
- 0:15e98ba559c1
First version
Who changed what in which revision?
User | Revision | Line number | New 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 | } |