Use a shared queue of X items - One thread adds items at random times - The other thread pulls at random times - They need to synchronize when the queue is full (producer) or empty (consumer)!

main.cpp

Committer:
vicara
Date:
2018-11-29
Revision:
1:58c5e61231be
Parent:
0:180517623995

File content as of revision 1:58c5e61231be:

#include "mbed.h"

typedef struct {
    int value;
} message_t;
const int queue_size = 10;
MemoryPool<message_t, queue_size> mpool;
Queue<message_t, queue_size> queue;
int elements_num = 0;

Mutex mutex;
ConditionVariable cond(mutex);
InterruptIn button(USER_BUTTON);
bool is_button_pressed = false;
 
Thread t1;
Thread t2;
Thread t3;

void start_producer(){
    
    while (true) 
    { 
        wait(rand()%3);
        mutex.lock();   
        int value = rand(); 
        while(elements_num == queue_size) {
            printf("The queue is full, cannot put.\n");
            cond.wait();
        } 
        message_t *message = mpool.alloc();
        message->value = value;
        queue.put(message);
        elements_num++;
        printf("PRODUCER: Put value %d \n", message->value);
        cond.notify_all();
        mutex.unlock();
    }
}

void start_consumer(){
    while (true) 
    { 
        wait(rand()%10);
        mutex.lock();
        while(elements_num == 0) {
            printf("The queue is empty. Nothing to consume.\n");
            cond.wait();
        }
        osEvent evt = queue.get();
        elements_num--;
        if (evt.status == osEventMessage) {
            message_t *message = (message_t*)evt.value.p;
            printf("CONSUMER: I got %d\n", message->value);
            mpool.free(message);
        }
        cond.notify_all();
        mutex.unlock();  
    }
}

void toggle (){
    is_button_pressed = true;
}

void print_status(){
    while (true) {
        if(is_button_pressed){
            mutex.lock();
            wait(2);
            printf("\n\nThere are %d elements in the queue\n\n", elements_num);
            wait(2);
            mutex.unlock();
            is_button_pressed = false;
        }
    }
}

int main() {
    button.rise(&toggle);
    t1.start(&start_producer);
    t2.start(&start_consumer);
    t3.start(&print_status);
}