Demonstrates a race condition

main.cpp

Committer:
noutram
Date:
2019-09-18
Revision:
5:5dcfbaa2e549
Parent:
4:e1c35030b91a

File content as of revision 5:5dcfbaa2e549:

#include "mbed.h"

#define N 1000000
#define RELEASED 0
#define PRESSED  1

#ifdef TARGET_NUCLEO_F429ZI
//#define ONBOARD
#endif

#ifdef ONBOARD
DigitalOut red_led(LED3);     //CountUp is in its critical section
DigitalOut yellow_led(LED2);  //CountDown is in its critical section
DigitalOut green_led(LED1);   //counter != 0
#else
DigitalOut red_led(PE_15);     //CountUp is in its critical section
DigitalOut yellow_led(PB_10);  //CountDown is in its critical section
DigitalOut green_led(PB_11);   //counter != 0
#endif

DigitalIn button(USER_BUTTON);

//Shared mutable state
volatile long long counter = 0; //Volatile means it must be stored in memory

//Increment the shared variable 
void countUp()
{
    //RED MEANS THE COUNT UP FUNCTION IS IN ITS CRITICAL SECTION
    red_led = 1;
    for (unsigned int n=0; n<N; n++) {
        counter++; 
        counter++;
        counter++;
        counter++;
        counter++;
        counter++;
        counter++;
        counter++;
        counter++;
        counter++; 
    }  
    red_led = 0; 
    
    //Last to finish turnes out the green light
    if (counter == 0) {
        green_led = 0;   
    }
}

//Decrement the shared variable
void countDown()
{
    //YELLOW MEANS THE COUNT DOWN FUNCTION IS IN ITS CRITICAL SECTION
    yellow_led = 1;
    for (unsigned int n=0; n<N; n++) {
        counter--;
        counter--;
        counter--;
        counter--;
        counter--;
        counter--;
        counter--;
        counter--;
        counter--;
        counter--;  
    }
    yellow_led = 0;
      
    //Last to finish turns out the green light  
    if (counter == 0) {
        green_led = 0;   
    }     
}
int main() {
    
    green_led = 1;
    Timeout t1;
    
    // TRY EACH OF THESE LINES IN TURN.
    // ALL IT DOES IS CHANGE THE TIMING OF THE ISR, NOT THE FUNCTION
    
    if (button == PRESSED) {
        //VERSION 2: short delay allowing main to be preempted - you might want to tweak this value
        t1.attach_us(&countDown, 15);
    } else {
        //VERSION 1: 2s - ENOUGH TIME FOR COUNTUP TO FINISH
        t1.attach(&countDown, 2);                   
    }
    
    //Run count up on the main thread
    countUp();
    
   
    //Now spin for ever
    while(1) { 
        wait(0.5);
    };
}