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@1:58c5e61231be, 2018-11-29 (annotated)
- Committer:
- vicara
- Date:
- Thu Nov 29 17:57:31 2018 +0000
- Revision:
- 1:58c5e61231be
- Parent:
- 0:180517623995
frunzia
Who changed what in which revision?
User | Revision | Line number | New 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 | } |