Demonstration of a spin lock
Dependencies: ELEC350-Practicals-FZ429
Fork of Task617Solution-mbedos-FZ429 by
Revision 8:ad00c9036add, committed 2017-11-09
- Comitter:
- noutram
- Date:
- Thu Nov 09 14:43:39 2017 +0000
- Parent:
- 7:bd75e7717b58
- Commit message:
- Demonstration of a spin lock
Changed in this revision
diff -r bd75e7717b58 -r ad00c9036add ELEC350-Practicals-FZ429.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ELEC350-Practicals-FZ429.lib Thu Nov 09 14:43:39 2017 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/University-of-Plymouth-Stage-2-and-3/code/ELEC350-Practicals-FZ429/#6f9f2e93a0be
diff -r bd75e7717b58 -r ad00c9036add main.cpp --- a/main.cpp Tue Oct 31 15:40:25 2017 +0000 +++ b/main.cpp Thu Nov 09 14:43:39 2017 +0000 @@ -1,84 +1,117 @@ #include "mbed.h" -#include "rtos.h" #include "string.h" #include <stdio.h> #include <ctype.h> +#include "sample_hardware.hpp" -#define DELAY 200 + +#define RED_DONE 1 +#define YELLOW_DONE 2 + -DigitalOut onBoardLED(LED1); -DigitalOut redLED(PE_15); -DigitalOut yellowLED(PB_10); -DigitalOut greenLED(PB_11); +//Function declarations +void countUP(); +void countDOWN(); +extern "C" void spinlock(volatile int *arg); +extern "C" void spinunlock(volatile int *arg); -DigitalIn onBoardSwitch(USER_BUTTON); -DigitalIn SW1(PE_12); -DigitalIn SW2(PE_14); +//MUTEX Lock +Mutex countLock; +volatile int _spinLock = 1; //Thread ID for the Main function (CMSIS API) osThreadId tidMain; -//Thread sychronisation primatives -Mutex lock1; -Mutex lock2; -unsigned long sw1Count = 0; -unsigned long sw2Count = 0; +//Stared mutable state +volatile int count = 0; -void thread1() +// ************************************************************* +// * TRY THIS WITH AND WITHOUT UNCOMMENTING THE FOLLOWING LINE * +// * Note the speed difference for this particular case. +// ************************************************************* + +//#define SPIN + +void inline increment() { - printf("Entering thread 1\n"); - while (true) { - yellowLED = 1; - - //Start critical section - lock1.lock(); - - sw1Count++; - printf("\nCount1 = %lu", sw1Count); - - Thread::wait(1); //1ms - - //End critical section - lock1.unlock(); - - if (SW1 == 1) { - lock2.lock(); - sw2Count--; - lock2.unlock(); - } - - yellowLED = 0; - Thread::wait(DELAY); - } + //**** Take lock **** + #ifdef SPIN + spinlock(&_spinLock); + #else + countLock.lock(); + #endif + + count++; + + //**** Release lock **** + #ifdef SPIN + spinunlock(&_spinLock); + #else + countLock.unlock(); + #endif } -void thread2() + + +void inline decrement() +{ + //**** Take lock **** + #ifdef SPIN + spinlock(&_spinLock); + #else + countLock.lock(); + #endif + + count--; + + //**** Release lock **** + #ifdef SPIN + spinunlock(&_spinLock); + #else + countLock.unlock(); + #endif +} +//Threads +void countUP() { - printf("Entering thread 2\n"); - while (true) { - redLED = 1; - - //Start critical section - lock2.lock(); - - sw2Count++; - printf("\nCount2 = %lu", sw2Count); - - Thread::wait(1); //1ms + redLED = 1; + + for (unsigned int n=0; n<100000; n++) { + increment(); + increment(); + increment(); + increment(); + increment(); + increment(); + increment(); + increment(); + increment(); + increment(); + } + + redLED = 0; + osSignalSet(tidMain, RED_DONE); //Signal main thread we are done +} + +void countDOWN() +{ + yellowLED = 1; + + for (unsigned int n=0; n<100000; n++) { + decrement(); + decrement(); + decrement(); + decrement(); + decrement(); + decrement(); + decrement(); + decrement(); + decrement(); + decrement(); + } - //End critical section - lock2.unlock(); - - if (SW2 == 1) { - lock1.lock(); - sw1Count--; - lock1.unlock(); - } - - redLED = 0; - Thread::wait(DELAY); - - } + yellowLED = 0; + osSignalSet(tidMain, YELLOW_DONE); //Signal main thread we are done } @@ -86,22 +119,36 @@ int main() { redLED = 0; yellowLED = 0; - greenLED = 0; - - //Main thread ID - tidMain = Thread::gettid(); + greenLED = 1; //Threads - Thread t1, t2; + Thread t1; + Thread t2; + tidMain = Thread::gettid(); - t1.start(thread1); - t2.start(thread2); - - printf("Main Thread\n"); - while (true) { - Thread::wait(osWaitForever); + //Press the switch to run concurrently + if (onBoardSwitch == 1) { + printf("Running sequntially\n"); + countUP(); + countDOWN(); + } else { + printf("Running concurrently\n"); + t1.start(countUP); + t2.start(countDOWN); + + //Wait for the ALL_ON signal + Thread::signal_wait(RED_DONE,osWaitForever); + Thread::signal_wait(YELLOW_DONE,osWaitForever); } + printf("Final result = %d\n", count); + if (count == 0) { + greenLED = 0; + } + + while(true); } + +
diff -r bd75e7717b58 -r ad00c9036add myasm.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/myasm.s Thu Nov 09 14:43:39 2017 +0000 @@ -0,0 +1,29 @@ + AREA asm_func, CODE, READONLY +; Export my_asm function location so that C compiler can find it and link + EXPORT myasm +myasm + + ; Write assmebler here + MOV R1, #0x20000000 + BX R1 ; THIS IS BAD + BX LR + + EXPORT spinlock +spinlock + LDREX R1,[R0] ;Read counter + SUBS R1, #1 ;Subtract 1 + ITT PL ;IF True True >= 0 + STREXPL R2,R1,[R0] ;TRY UPDATE + CMPPL R2,#0 ;SUCCEED? + BNE spinlock + BX LR + + EXPORT spinunlock +spinunlock + LDREX R1,[R0] + ADD R1,#1 + STREX R2,R1,[R0] + CMP R2,#0 + BNE spinunlock + BX LR + END \ No newline at end of file