Demonstration of a spin lock

Dependencies:   ELEC350-Practicals-FZ429

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

main.cpp

Committer:
noutram
Date:
2017-11-09
Revision:
8:ad00c9036add
Parent:
7:bd75e7717b58

File content as of revision 8:ad00c9036add:

#include "mbed.h"
#include "string.h"
#include <stdio.h>
#include <ctype.h>
#include "sample_hardware.hpp"


#define RED_DONE 1
#define YELLOW_DONE 2


//Function declarations
void countUP();
void countDOWN();
extern "C" void spinlock(volatile int *arg);
extern "C" void spinunlock(volatile int *arg);

//MUTEX Lock
Mutex countLock;
volatile int _spinLock = 1;

//Thread ID for the Main function (CMSIS API)
osThreadId tidMain;

//Stared mutable state
volatile int count = 0;

// *************************************************************
// * TRY THIS WITH AND WITHOUT UNCOMMENTING THE FOLLOWING LINE *
// * Note the speed difference for this particular case.
// *************************************************************

//#define SPIN

void inline increment()
{
  //**** Take lock ****
    #ifdef SPIN
    spinlock(&_spinLock); 
    #else
    countLock.lock();
    #endif
    
    count++;
    
    //**** Release lock ****
    #ifdef SPIN
  spinunlock(&_spinLock);   
    #else
    countLock.unlock();
    #endif
}



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()
{
    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();
    }   
        
    yellowLED = 0;    
    osSignalSet(tidMain, YELLOW_DONE); //Signal main thread we are done
}


//Main thread
int main() {
    redLED    = 0;
    yellowLED = 0;
    greenLED  = 1;
    
    //Threads
    Thread t1;
    Thread t2;
    tidMain = Thread::gettid();  
    
    //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);
}