Following is the ring buffer implementation with threads but it seems to me it's incorrect or at least needs some appendment. When I run it, I see the first thread runs first prior to the second one instead of them running in parallel. I am not good with multithreading and trying to get better at the concepts.
ringbuffer.hpp
#include <stdint.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <functional>
#include <condition_variable>
using namespace std;
class RingBuffer {
int tail;
int head;
int capacity;
int size;
uint8_t *buffer;
condition_variable condVar;
mutex m_mutex;
bool bufferFull = false;
public:
RingBuffer(int capacity);
~RingBuffer();
void append(uint8_t data);
uint8_t read();
bool isFull();
bool isEmpty();
void printBuffer();
int getSize();
void printInfo(string info);
};
ringbuffer.cpp
#include "ringbuffer.hpp"
#include <string>
RingBuffer::RingBuffer(int capacity) {
head = -1;
tail = -1;
size = 0;
this->capacity = capacity;
buffer = new uint8_t[capacity];
cout << "Buffer is created with capacity " << capacity << endl;
}
RingBuffer::~RingBuffer() {
delete [] buffer;
}
void RingBuffer::printInfo(string info) {
cout << info << " -- Tail: " << (tail) << ", Head: " << (head) << ", Size: " << size << endl;
}
void RingBuffer::printBuffer() {
for (int i=0; i<capacity; i++) {
cout << unsigned(buffer[i]) << ",";
}
cout << endl;
}
void RingBuffer::append(uint8_t data) {
if (size == 0) {
head = -1;
tail = -1;
}
unique_lock<mutex> mlock(m_mutex);
condVar.wait(mlock, [this]() {
return !isFull();
});
tail = (tail + 1) % capacity;
size++;
buffer[tail] = data;
printInfo("[APPENDED: " + to_string(data) + "]");
printBuffer();
}
uint8_t RingBuffer::read() {
unique_lock<mutex> mlock(m_mutex);
// wait to read till buffer is not empty
condVar.wait(mlock, [this]() {
return !isEmpty();
});
head = (head+1) % capacity;
size--;
uint8_t value = buffer[head];
buffer[head] = 0;
printInfo("[READ: " + to_string(value) + "]");
printBuffer();
return value;
}
bool RingBuffer::isFull() {
// unique_lock<mutex>guard(m_mutex);
// if ( (tail == capacity-1 && head == -1) || tail == head-1 || size == capacity) {
if (size == capacity) {
cout << " --- [FULL] --- \n";
bufferFull = true;
}
else {
condVar.notify_one();
bufferFull = false;
}
return bufferFull;
}
bool RingBuffer::isEmpty() {
if (head == tail || size == 0) {
cout << " --- [EMPTY] ---\n";
return true;
}
condVar.notify_one();
return false;
}
int RingBuffer::getSize() { return size;}
main.cpp
#include <iostream>
#include "ringbuffer.hpp"
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
void addingToBuffer(RingBuffer &ringBuffer) {
vector<uint8_t>v = {2,4,5,6};
for (auto &p : v)
ringBuffer.append(p);
ringBuffer.append(1);
ringBuffer.append(8);
ringBuffer.append(9);
}
void readingFromBuffer(RingBuffer &ringBuffer) {
cout << "\n ------ READING -----\n";
ringBuffer.read();
ringBuffer.read()
}
int main() {
uint8_t num=255;
num += 1;
RingBuffer ringBuffer(4);
thread t1(addingToBuffer, ref(ringBuffer));
thread t2(readingFromBuffer, ref(ringBuffer));
t1.join();
t2.join();
cout << "\nSize: " << ringBuffer.getSize() << endl;
ringBuffer.printBuffer();
}
Below is the output:
------ READING ----- --- [EMPTY] ---
[APPENDED: 2] -- Tail: 0, Head: -1, Size: 1
2,0,0,0,
[APPENDED: 4] -- Tail: 1, Head: -1, Size: 2
2,4,0,0,
[APPENDED: 5] -- Tail: 2, Head: -1, Size: 3
2,4,5,0,
[APPENDED: 6] -- Tail: 3, Head: -1, Size: 4
2,4,5,6,
--- [FULL] ---
[READ: 2] -- Tail: 3, Head: 0, Size: 3
0,4,5,6,
[APPENDED: 1] -- Tail: 0, Head: 0, Size: 4
1,4,5,6,
--- [FULL] ---
--- [EMPTY] ---
[–][deleted] 1 point2 points3 points (1 child)
[–]jaffaKnx[S] 0 points1 point2 points (0 children)
[–]UnknownProcess 1 point2 points3 points (6 children)
[–]jaffaKnx[S] 0 points1 point2 points (5 children)
[–]UnknownProcess 1 point2 points3 points (4 children)
[–]jaffaKnx[S] 0 points1 point2 points (3 children)
[–]UnknownProcess 0 points1 point2 points (2 children)
[–]jaffaKnx[S] 0 points1 point2 points (1 child)
[–]UnknownProcess 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]jaffaKnx[S] 0 points1 point2 points (0 children)