Demonstration of deadlocks by adding a small delay

Dependencies:   mbed-rtos mbed

Committer:
noutram
Date:
Tue Mar 08 12:26:28 2016 +0000
Revision:
1:4fb27aea76b2
Parent:
0:f916cefba2f4
Child:
2:70084af839d3
Solution for 6.1.5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
noutram 0:f916cefba2f4 1 #include "mbed.h"
noutram 0:f916cefba2f4 2 #include "rtos.h"
noutram 0:f916cefba2f4 3
noutram 0:f916cefba2f4 4 #define RED_DONE 1
noutram 0:f916cefba2f4 5 #define YELLOW_DONE 2
noutram 0:f916cefba2f4 6
noutram 0:f916cefba2f4 7
noutram 0:f916cefba2f4 8 //Function declarations
noutram 0:f916cefba2f4 9 void countUP(void const *args);
noutram 0:f916cefba2f4 10 void countDOWN(void const *args);
noutram 0:f916cefba2f4 11
noutram 0:f916cefba2f4 12 //Digital outputs
noutram 0:f916cefba2f4 13 DigitalOut onBoardLED(LED1);
noutram 0:f916cefba2f4 14 DigitalOut redLED(D7);
noutram 0:f916cefba2f4 15 DigitalOut yellowLED(D6);
noutram 0:f916cefba2f4 16 DigitalOut greenLED(D5);
noutram 0:f916cefba2f4 17
noutram 0:f916cefba2f4 18 //Digital inputs
noutram 0:f916cefba2f4 19 DigitalIn onBoardSwitch(USER_BUTTON);
noutram 0:f916cefba2f4 20 DigitalIn SW1(D4);
noutram 0:f916cefba2f4 21 DigitalIn SW2(D3);
noutram 0:f916cefba2f4 22
noutram 1:4fb27aea76b2 23 //MUTEX Lock
noutram 1:4fb27aea76b2 24 Mutex *countLock;
noutram 0:f916cefba2f4 25
noutram 0:f916cefba2f4 26 //Thread ID for the Main function (CMSIS API)
noutram 0:f916cefba2f4 27 osThreadId tidMain;
noutram 0:f916cefba2f4 28
noutram 0:f916cefba2f4 29 //Stared mutable state
noutram 0:f916cefba2f4 30 volatile long long count = 0;
noutram 0:f916cefba2f4 31
noutram 0:f916cefba2f4 32 //Threads
noutram 0:f916cefba2f4 33 void countUP(void const *args)
noutram 0:f916cefba2f4 34 {
noutram 0:f916cefba2f4 35 redLED = 1;
noutram 0:f916cefba2f4 36
noutram 0:f916cefba2f4 37 for (unsigned int n=0; n<10000; n++) {
noutram 1:4fb27aea76b2 38 //Take lock
noutram 1:4fb27aea76b2 39 countLock->lock();
noutram 1:4fb27aea76b2 40
noutram 1:4fb27aea76b2 41 //Critical section(s)
noutram 0:f916cefba2f4 42 count++;
noutram 0:f916cefba2f4 43 count++;
noutram 0:f916cefba2f4 44 count++;
noutram 0:f916cefba2f4 45 count++;
noutram 0:f916cefba2f4 46 count++;
noutram 0:f916cefba2f4 47 count++;
noutram 0:f916cefba2f4 48 count++;
noutram 0:f916cefba2f4 49 count++;
noutram 0:f916cefba2f4 50 count++;
noutram 0:f916cefba2f4 51 count++;
noutram 1:4fb27aea76b2 52
noutram 1:4fb27aea76b2 53 //Release lock
noutram 1:4fb27aea76b2 54 countLock->unlock();
noutram 0:f916cefba2f4 55 }
noutram 0:f916cefba2f4 56
noutram 0:f916cefba2f4 57 redLED = 0;
noutram 0:f916cefba2f4 58 osSignalSet(tidMain, RED_DONE); //Signal main thread we are done
noutram 0:f916cefba2f4 59 }
noutram 0:f916cefba2f4 60
noutram 0:f916cefba2f4 61 void countDOWN(void const *args)
noutram 0:f916cefba2f4 62 {
noutram 0:f916cefba2f4 63 yellowLED = 1;
noutram 0:f916cefba2f4 64
noutram 0:f916cefba2f4 65 for (unsigned int n=0; n<10000; n++) {
noutram 1:4fb27aea76b2 66 //Take lock
noutram 1:4fb27aea76b2 67 countLock->lock();
noutram 1:4fb27aea76b2 68
noutram 1:4fb27aea76b2 69 //Critical section(s)
noutram 0:f916cefba2f4 70 count--;
noutram 0:f916cefba2f4 71 count--;
noutram 0:f916cefba2f4 72 count--;
noutram 0:f916cefba2f4 73 count--;
noutram 0:f916cefba2f4 74 count--;
noutram 0:f916cefba2f4 75 count--;
noutram 0:f916cefba2f4 76 count--;
noutram 0:f916cefba2f4 77 count--;
noutram 0:f916cefba2f4 78 count--;
noutram 1:4fb27aea76b2 79 count--;
noutram 1:4fb27aea76b2 80
noutram 1:4fb27aea76b2 81 //Release lock
noutram 1:4fb27aea76b2 82 countLock->unlock();
noutram 0:f916cefba2f4 83 }
noutram 0:f916cefba2f4 84
noutram 0:f916cefba2f4 85 osSignalSet(tidMain, YELLOW_DONE); //Signal main thread we are done
noutram 0:f916cefba2f4 86 yellowLED = 0;
noutram 0:f916cefba2f4 87 }
noutram 0:f916cefba2f4 88
noutram 0:f916cefba2f4 89
noutram 0:f916cefba2f4 90 //Main thread
noutram 0:f916cefba2f4 91 int main() {
noutram 0:f916cefba2f4 92 redLED = 0;
noutram 0:f916cefba2f4 93 yellowLED = 0;
noutram 0:f916cefba2f4 94 greenLED = 1;
noutram 0:f916cefba2f4 95
noutram 0:f916cefba2f4 96 //Main thread ID
noutram 0:f916cefba2f4 97 tidMain = Thread::gettid();
noutram 0:f916cefba2f4 98
noutram 1:4fb27aea76b2 99 //Create lock
noutram 1:4fb27aea76b2 100 countLock = new Mutex();
noutram 1:4fb27aea76b2 101
noutram 0:f916cefba2f4 102 //Press the switch to run concurrently
noutram 0:f916cefba2f4 103 if (onBoardSwitch == 1) {
noutram 0:f916cefba2f4 104 printf("Running sequntially\n");
noutram 0:f916cefba2f4 105 countUP(NULL);
noutram 0:f916cefba2f4 106 countDOWN(NULL);
noutram 0:f916cefba2f4 107 } else {
noutram 0:f916cefba2f4 108 printf("Running concurrently\n");
noutram 0:f916cefba2f4 109 Thread t1(countUP);
noutram 0:f916cefba2f4 110 Thread t2(countDOWN);
noutram 0:f916cefba2f4 111
noutram 0:f916cefba2f4 112 //Wait for the ALL_ON signal
noutram 0:f916cefba2f4 113 Thread::signal_wait(RED_DONE,osWaitForever);
noutram 0:f916cefba2f4 114 Thread::signal_wait(YELLOW_DONE,osWaitForever);
noutram 0:f916cefba2f4 115 }
noutram 0:f916cefba2f4 116
noutram 0:f916cefba2f4 117 printf("Final result = %lld\n", count);
noutram 0:f916cefba2f4 118 if (count == 0) {
noutram 0:f916cefba2f4 119 greenLED = 0;
noutram 0:f916cefba2f4 120 }
noutram 1:4fb27aea76b2 121
noutram 1:4fb27aea76b2 122 //Tidy
noutram 1:4fb27aea76b2 123 delete countLock;
noutram 1:4fb27aea76b2 124
noutram 0:f916cefba2f4 125 while(true);
noutram 0:f916cefba2f4 126 }