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)!

Committer:
vicara
Date:
Thu Nov 29 17:57:31 2018 +0000
Revision:
1:58c5e61231be
Parent:
0:180517623995
frunzia

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vicara 0:180517623995 1 #include "mbed.h"
vicara 0:180517623995 2
vicara 1:58c5e61231be 3 typedef struct {
vicara 1:58c5e61231be 4 int value;
vicara 1:58c5e61231be 5 } message_t;
vicara 1:58c5e61231be 6 const int queue_size = 10;
vicara 1:58c5e61231be 7 MemoryPool<message_t, queue_size> mpool;
vicara 1:58c5e61231be 8 Queue<message_t, queue_size> queue;
vicara 1:58c5e61231be 9 int elements_num = 0;
vicara 0:180517623995 10
vicara 0:180517623995 11 Mutex mutex;
vicara 0:180517623995 12 ConditionVariable cond(mutex);
vicara 0:180517623995 13 InterruptIn button(USER_BUTTON);
vicara 1:58c5e61231be 14 bool is_button_pressed = false;
vicara 0:180517623995 15
vicara 0:180517623995 16 Thread t1;
vicara 0:180517623995 17 Thread t2;
vicara 0:180517623995 18 Thread t3;
vicara 0:180517623995 19
vicara 0:180517623995 20 void start_producer(){
vicara 1:58c5e61231be 21
vicara 0:180517623995 22 while (true)
vicara 0:180517623995 23 {
vicara 1:58c5e61231be 24 wait(rand()%3);
vicara 1:58c5e61231be 25 mutex.lock();
vicara 1:58c5e61231be 26 int value = rand();
vicara 1:58c5e61231be 27 while(elements_num == queue_size) {
vicara 1:58c5e61231be 28 printf("The queue is full, cannot put.\n");
vicara 1:58c5e61231be 29 cond.wait();
vicara 0:180517623995 30 }
vicara 1:58c5e61231be 31 message_t *message = mpool.alloc();
vicara 1:58c5e61231be 32 message->value = value;
vicara 1:58c5e61231be 33 queue.put(message);
vicara 1:58c5e61231be 34 elements_num++;
vicara 1:58c5e61231be 35 printf("PRODUCER: Put value %d \n", message->value);
vicara 1:58c5e61231be 36 cond.notify_all();
vicara 1:58c5e61231be 37 mutex.unlock();
vicara 0:180517623995 38 }
vicara 0:180517623995 39 }
vicara 0:180517623995 40
vicara 0:180517623995 41 void start_consumer(){
vicara 0:180517623995 42 while (true)
vicara 0:180517623995 43 {
vicara 1:58c5e61231be 44 wait(rand()%10);
vicara 1:58c5e61231be 45 mutex.lock();
vicara 1:58c5e61231be 46 while(elements_num == 0) {
vicara 1:58c5e61231be 47 printf("The queue is empty. Nothing to consume.\n");
vicara 1:58c5e61231be 48 cond.wait();
vicara 1:58c5e61231be 49 }
vicara 1:58c5e61231be 50 osEvent evt = queue.get();
vicara 1:58c5e61231be 51 elements_num--;
vicara 1:58c5e61231be 52 if (evt.status == osEventMessage) {
vicara 1:58c5e61231be 53 message_t *message = (message_t*)evt.value.p;
vicara 1:58c5e61231be 54 printf("CONSUMER: I got %d\n", message->value);
vicara 1:58c5e61231be 55 mpool.free(message);
vicara 1:58c5e61231be 56 }
vicara 1:58c5e61231be 57 cond.notify_all();
vicara 1:58c5e61231be 58 mutex.unlock();
vicara 0:180517623995 59 }
vicara 0:180517623995 60 }
vicara 0:180517623995 61
vicara 0:180517623995 62 void toggle (){
vicara 0:180517623995 63 is_button_pressed = true;
vicara 0:180517623995 64 }
vicara 0:180517623995 65
vicara 0:180517623995 66 void print_status(){
vicara 0:180517623995 67 while (true) {
vicara 0:180517623995 68 if(is_button_pressed){
vicara 0:180517623995 69 mutex.lock();
vicara 0:180517623995 70 wait(2);
vicara 1:58c5e61231be 71 printf("\n\nThere are %d elements in the queue\n\n", elements_num);
vicara 0:180517623995 72 wait(2);
vicara 0:180517623995 73 mutex.unlock();
vicara 0:180517623995 74 is_button_pressed = false;
vicara 0:180517623995 75 }
vicara 0:180517623995 76 }
vicara 0:180517623995 77 }
vicara 0:180517623995 78
vicara 0:180517623995 79 int main() {
vicara 0:180517623995 80 button.rise(&toggle);
vicara 0:180517623995 81 t1.start(&start_producer);
vicara 0:180517623995 82 t2.start(&start_consumer);
vicara 0:180517623995 83 t3.start(&print_status);
vicara 0:180517623995 84 }