Demonstration of a spin lock

Dependencies:   ELEC350-Practicals-FZ429

Fork of Task617Solution-mbedos-FZ429 by University of Plymouth - Stages 1, 2 and 3

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?

UserRevisionLine numberNew 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