-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathblocking_ring.h
More file actions
91 lines (80 loc) · 2.01 KB
/
blocking_ring.h
File metadata and controls
91 lines (80 loc) · 2.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//
// Created by jessejcw@gmail.com on 2/28/17.
//
#ifndef BLOCKING_RING_H
#define BLOCKING_RING_H
#include <mutex>
#include <condition_variable>
// concurrent ring buffer
template <typename T, int SZ, typename ST=int>
class blocking_ring {
typedef T VALUE_T;
typedef ST SIZE_T;
std::mutex m_mutex;
std::condition_variable m_cond;
protected:
VALUE_T m_buffer[SZ];
SIZE_T m_size;
SIZE_T m_front;
SIZE_T m_back;
public:
blocking_ring() {
std::unique_lock<std::mutex> mlock(m_mutex);
clear();
}
~blocking_ring(){}
void push(const VALUE_T& x) {
std::unique_lock<std::mutex> mlock(m_mutex);
push();
back() = x;
mlock.unlock();
m_cond.notify_one();
}
void pop() {
std::unique_lock<std::mutex> mlock(m_mutex);
while ( m_size == 0) {
m_cond.wait(mlock);
}
m_size--;
m_front = (m_front+1) % SZ;
}
void back_erase(const SIZE_T n) {
std::unique_lock<std::mutex> mlock(m_mutex);
if (n >= m_size)
clear();
else {
m_size -= n;
m_back = (m_front + m_size -1) % SZ;
}
}
void front_erase(const SIZE_T n) {
std::unique_lock<std::mutex> mlock(m_mutex);
if (n >= m_size)
clear();
else {
m_size -= n;
m_front = (m_front+n) % SZ;
}
}
private:
SIZE_T size() const {return m_size;}
SIZE_T max_size() const { return SZ;}
bool empty() const { return m_size == 0;}
bool full() const { return m_size == SZ;}
VALUE_T& front() { return m_buffer[m_front];}
VALUE_T& back() { return m_buffer[m_back];}
void clear() {
m_size = 0;
m_front = 0;
m_back = SZ-1;
}
void push() {
m_back = (m_back+1) % SZ;
if (size() == SZ) {
m_front = (m_front + 1) % SZ;
} else {
m_size++;
}
}
};
#endif //BLOCKING_RING