![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Demonstration of a spin lock
Dependencies: ELEC350-Practicals-FZ429
Fork of Task617Solution-mbedos-FZ429 by
main.cpp@8:ad00c9036add, 2017-11-09 (annotated)
- Committer:
- noutram
- Date:
- Thu Nov 09 14:43:39 2017 +0000
- Revision:
- 8:ad00c9036add
- Parent:
- 7:bd75e7717b58
Demonstration of a spin lock
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
noutram | 0:f916cefba2f4 | 1 | #include "mbed.h" |
noutram | 2:70084af839d3 | 2 | #include "string.h" |
noutram | 2:70084af839d3 | 3 | #include <stdio.h> |
noutram | 2:70084af839d3 | 4 | #include <ctype.h> |
noutram | 8:ad00c9036add | 5 | #include "sample_hardware.hpp" |
noutram | 0:f916cefba2f4 | 6 | |
noutram | 8:ad00c9036add | 7 | |
noutram | 8:ad00c9036add | 8 | #define RED_DONE 1 |
noutram | 8:ad00c9036add | 9 | #define YELLOW_DONE 2 |
noutram | 8:ad00c9036add | 10 | |
noutram | 0:f916cefba2f4 | 11 | |
noutram | 8:ad00c9036add | 12 | //Function declarations |
noutram | 8:ad00c9036add | 13 | void countUP(); |
noutram | 8:ad00c9036add | 14 | void countDOWN(); |
noutram | 8:ad00c9036add | 15 | extern "C" void spinlock(volatile int *arg); |
noutram | 8:ad00c9036add | 16 | extern "C" void spinunlock(volatile int *arg); |
noutram | 0:f916cefba2f4 | 17 | |
noutram | 8:ad00c9036add | 18 | //MUTEX Lock |
noutram | 8:ad00c9036add | 19 | Mutex countLock; |
noutram | 8:ad00c9036add | 20 | volatile int _spinLock = 1; |
noutram | 0:f916cefba2f4 | 21 | |
noutram | 0:f916cefba2f4 | 22 | //Thread ID for the Main function (CMSIS API) |
noutram | 0:f916cefba2f4 | 23 | osThreadId tidMain; |
noutram | 0:f916cefba2f4 | 24 | |
noutram | 8:ad00c9036add | 25 | //Stared mutable state |
noutram | 8:ad00c9036add | 26 | volatile int count = 0; |
noutram | 2:70084af839d3 | 27 | |
noutram | 8:ad00c9036add | 28 | // ************************************************************* |
noutram | 8:ad00c9036add | 29 | // * TRY THIS WITH AND WITHOUT UNCOMMENTING THE FOLLOWING LINE * |
noutram | 8:ad00c9036add | 30 | // * Note the speed difference for this particular case. |
noutram | 8:ad00c9036add | 31 | // ************************************************************* |
noutram | 8:ad00c9036add | 32 | |
noutram | 8:ad00c9036add | 33 | //#define SPIN |
noutram | 8:ad00c9036add | 34 | |
noutram | 8:ad00c9036add | 35 | void inline increment() |
noutram | 4:dae8898e55fe | 36 | { |
noutram | 8:ad00c9036add | 37 | //**** Take lock **** |
noutram | 8:ad00c9036add | 38 | #ifdef SPIN |
noutram | 8:ad00c9036add | 39 | spinlock(&_spinLock); |
noutram | 8:ad00c9036add | 40 | #else |
noutram | 8:ad00c9036add | 41 | countLock.lock(); |
noutram | 8:ad00c9036add | 42 | #endif |
noutram | 8:ad00c9036add | 43 | |
noutram | 8:ad00c9036add | 44 | count++; |
noutram | 8:ad00c9036add | 45 | |
noutram | 8:ad00c9036add | 46 | //**** Release lock **** |
noutram | 8:ad00c9036add | 47 | #ifdef SPIN |
noutram | 8:ad00c9036add | 48 | spinunlock(&_spinLock); |
noutram | 8:ad00c9036add | 49 | #else |
noutram | 8:ad00c9036add | 50 | countLock.unlock(); |
noutram | 8:ad00c9036add | 51 | #endif |
noutram | 2:70084af839d3 | 52 | } |
noutram | 2:70084af839d3 | 53 | |
noutram | 8:ad00c9036add | 54 | |
noutram | 8:ad00c9036add | 55 | |
noutram | 8:ad00c9036add | 56 | void inline decrement() |
noutram | 8:ad00c9036add | 57 | { |
noutram | 8:ad00c9036add | 58 | //**** Take lock **** |
noutram | 8:ad00c9036add | 59 | #ifdef SPIN |
noutram | 8:ad00c9036add | 60 | spinlock(&_spinLock); |
noutram | 8:ad00c9036add | 61 | #else |
noutram | 8:ad00c9036add | 62 | countLock.lock(); |
noutram | 8:ad00c9036add | 63 | #endif |
noutram | 8:ad00c9036add | 64 | |
noutram | 8:ad00c9036add | 65 | count--; |
noutram | 8:ad00c9036add | 66 | |
noutram | 8:ad00c9036add | 67 | //**** Release lock **** |
noutram | 8:ad00c9036add | 68 | #ifdef SPIN |
noutram | 8:ad00c9036add | 69 | spinunlock(&_spinLock); |
noutram | 8:ad00c9036add | 70 | #else |
noutram | 8:ad00c9036add | 71 | countLock.unlock(); |
noutram | 8:ad00c9036add | 72 | #endif |
noutram | 8:ad00c9036add | 73 | } |
noutram | 8:ad00c9036add | 74 | //Threads |
noutram | 8:ad00c9036add | 75 | void countUP() |
noutram | 0:f916cefba2f4 | 76 | { |
noutram | 8:ad00c9036add | 77 | redLED = 1; |
noutram | 8:ad00c9036add | 78 | |
noutram | 8:ad00c9036add | 79 | for (unsigned int n=0; n<100000; n++) { |
noutram | 8:ad00c9036add | 80 | increment(); |
noutram | 8:ad00c9036add | 81 | increment(); |
noutram | 8:ad00c9036add | 82 | increment(); |
noutram | 8:ad00c9036add | 83 | increment(); |
noutram | 8:ad00c9036add | 84 | increment(); |
noutram | 8:ad00c9036add | 85 | increment(); |
noutram | 8:ad00c9036add | 86 | increment(); |
noutram | 8:ad00c9036add | 87 | increment(); |
noutram | 8:ad00c9036add | 88 | increment(); |
noutram | 8:ad00c9036add | 89 | increment(); |
noutram | 8:ad00c9036add | 90 | } |
noutram | 8:ad00c9036add | 91 | |
noutram | 8:ad00c9036add | 92 | redLED = 0; |
noutram | 8:ad00c9036add | 93 | osSignalSet(tidMain, RED_DONE); //Signal main thread we are done |
noutram | 8:ad00c9036add | 94 | } |
noutram | 8:ad00c9036add | 95 | |
noutram | 8:ad00c9036add | 96 | void countDOWN() |
noutram | 8:ad00c9036add | 97 | { |
noutram | 8:ad00c9036add | 98 | yellowLED = 1; |
noutram | 8:ad00c9036add | 99 | |
noutram | 8:ad00c9036add | 100 | for (unsigned int n=0; n<100000; n++) { |
noutram | 8:ad00c9036add | 101 | decrement(); |
noutram | 8:ad00c9036add | 102 | decrement(); |
noutram | 8:ad00c9036add | 103 | decrement(); |
noutram | 8:ad00c9036add | 104 | decrement(); |
noutram | 8:ad00c9036add | 105 | decrement(); |
noutram | 8:ad00c9036add | 106 | decrement(); |
noutram | 8:ad00c9036add | 107 | decrement(); |
noutram | 8:ad00c9036add | 108 | decrement(); |
noutram | 8:ad00c9036add | 109 | decrement(); |
noutram | 8:ad00c9036add | 110 | decrement(); |
noutram | 8:ad00c9036add | 111 | } |
noutram | 1:4fb27aea76b2 | 112 | |
noutram | 8:ad00c9036add | 113 | yellowLED = 0; |
noutram | 8:ad00c9036add | 114 | osSignalSet(tidMain, YELLOW_DONE); //Signal main thread we are done |
noutram | 0:f916cefba2f4 | 115 | } |
noutram | 0:f916cefba2f4 | 116 | |
noutram | 4:dae8898e55fe | 117 | |
noutram | 0:f916cefba2f4 | 118 | //Main thread |
noutram | 0:f916cefba2f4 | 119 | int main() { |
noutram | 0:f916cefba2f4 | 120 | redLED = 0; |
noutram | 0:f916cefba2f4 | 121 | yellowLED = 0; |
noutram | 8:ad00c9036add | 122 | greenLED = 1; |
noutram | 0:f916cefba2f4 | 123 | |
noutram | 4:dae8898e55fe | 124 | //Threads |
noutram | 8:ad00c9036add | 125 | Thread t1; |
noutram | 8:ad00c9036add | 126 | Thread t2; |
noutram | 8:ad00c9036add | 127 | tidMain = Thread::gettid(); |
noutram | 6:d16ce38e9b8a | 128 | |
noutram | 8:ad00c9036add | 129 | //Press the switch to run concurrently |
noutram | 8:ad00c9036add | 130 | if (onBoardSwitch == 1) { |
noutram | 8:ad00c9036add | 131 | printf("Running sequntially\n"); |
noutram | 8:ad00c9036add | 132 | countUP(); |
noutram | 8:ad00c9036add | 133 | countDOWN(); |
noutram | 8:ad00c9036add | 134 | } else { |
noutram | 8:ad00c9036add | 135 | printf("Running concurrently\n"); |
noutram | 8:ad00c9036add | 136 | t1.start(countUP); |
noutram | 8:ad00c9036add | 137 | t2.start(countDOWN); |
noutram | 8:ad00c9036add | 138 | |
noutram | 8:ad00c9036add | 139 | //Wait for the ALL_ON signal |
noutram | 8:ad00c9036add | 140 | Thread::signal_wait(RED_DONE,osWaitForever); |
noutram | 8:ad00c9036add | 141 | Thread::signal_wait(YELLOW_DONE,osWaitForever); |
noutram | 0:f916cefba2f4 | 142 | } |
noutram | 0:f916cefba2f4 | 143 | |
noutram | 8:ad00c9036add | 144 | printf("Final result = %d\n", count); |
noutram | 8:ad00c9036add | 145 | if (count == 0) { |
noutram | 8:ad00c9036add | 146 | greenLED = 0; |
noutram | 8:ad00c9036add | 147 | } |
noutram | 8:ad00c9036add | 148 | |
noutram | 8:ad00c9036add | 149 | while(true); |
noutram | 0:f916cefba2f4 | 150 | } |
noutram | 2:70084af839d3 | 151 | |
noutram | 8:ad00c9036add | 152 | |
noutram | 8:ad00c9036add | 153 | |
noutram | 2:70084af839d3 | 154 |