GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 47.1% 32 / 0 / 68
Functions: 60.0% 6 / 0 / 10
Branches: 27.5% 11 / 0 / 40

core/mpmc_bounded_queue.h
Line Branch Exec Source
1 #include <vector>
2
3 template <typename T>
4 class circular_buffer
5 {
6 public:
7
8 typedef size_t size_type;
9 typedef T value_type;
10
11 private:
12 std::vector<T> array;
13 const size_type max_size;
14 size_type head;
15 size_type tail;
16 size_type size;
17
18 public:
19
20 453 circular_buffer(size_type capacity) :
21
1/2
✓ Branch 4 → 5 taken 453 times.
✗ Branch 4 → 7 not taken.
906 array(capacity),
22 453 max_size(capacity),
23 453 head(0),
24 453 tail(0),
25 453 size(0)
26 {
27 453 }
28
29 2263 bool empty() const
30 {
31 2263 return size == 0;
32 }
33
34 bool full() const
35 {
36 assert(size <= max_size);
37 return size == max_size;
38 }
39
40 bool push_front(T&& item)
41 {
42 if (full())
43 return false;
44
45 array[head] = std::move(item);
46 head = (head + 1) % max_size;
47 ++size;
48
49 return true;
50 }
51
52 bool pop_back(T* pItem)
53 {
54 if (empty())
55 return false;
56
57 *pItem = std::move(array[tail]);
58 tail = (tail + 1) % max_size;
59 --size;
60
61 return true;
62 }
63
64 size_type capacity() const
65 {
66 return max_size;
67 }
68 };
69
70 #include <mutex>
71 #include <condition_variable>
72
73 template <typename T>
74 class mpmc_bounded_queue
75 {
76 public:
77 typedef circular_buffer<T> container_type;
78 typedef typename container_type::size_type size_type;
79 typedef typename container_type::value_type value_type;
80
81 private:
82 mpmc_bounded_queue(const mpmc_bounded_queue&); // Disabled copy constructor
83 mpmc_bounded_queue& operator = (const mpmc_bounded_queue&); // Disabled assign operator
84
85 container_type m_container;
86 std::mutex m_mutex;
87 std::condition_variable m_not_empty;
88 std::condition_variable m_not_full;
89 bool finished;
90
91 public:
92 453 mpmc_bounded_queue(size_type capacity) :
93 453 m_container(capacity),
94 453 finished(false)
95 {
96 453 }
97
98 size_type capacity() const
99 {
100 return m_container.capacity();
101 }
102
103 453 void finish()
104 {
105
1/2
✓ Branch 2 → 3 taken 453 times.
✗ Branch 2 → 8 not taken.
453 std::unique_lock<std::mutex> lock(m_mutex);
106
1/2
✓ Branch 3 → 4 taken 453 times.
✗ Branch 3 → 6 not taken.
453 if (finished == false) {
107 453 finished = true;
108 453 m_not_full.notify_all();
109 453 m_not_empty.notify_all();
110 }
111 453 }
112
113 bool is_finished()
114 {
115 std::unique_lock<std::mutex> lock(m_mutex);
116 return finished;
117 }
118
119 bool push_front(T&& item)
120 {
121 std::unique_lock<std::mutex> lock(m_mutex);
122 if (finished) {
123 return false;
124 }
125 while(m_container.full())
126 {
127 m_not_full.wait(lock);
128 if (finished) {
129 return false;
130 }
131 }
132 m_container.push_front(std::move(item));
133 lock.unlock();
134 m_not_empty.notify_one();
135 return true;
136 }
137
138 1812 bool pop_back(value_type* pItem)
139 {
140
1/2
✓ Branch 2 → 3 taken 1812 times.
✗ Branch 2 → 21 not taken.
1812 std::unique_lock<std::mutex> lock(m_mutex);
141
2/2
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 5 taken 1810 times.
1812 if (finished) {
142 2 return false;
143 }
144
1/2
✓ Branch 11 → 6 taken 1810 times.
✗ Branch 11 → 12 not taken.
1810 while(m_container.empty())
145 {
146
1/2
✓ Branch 6 → 7 taken 1810 times.
✗ Branch 6 → 19 not taken.
1810 m_not_empty.wait(lock);
147
1/2
✓ Branch 7 → 8 taken 1810 times.
✗ Branch 7 → 9 not taken.
1810 if (finished) {
148 1810 return false;
149 }
150 }
151 m_container.pop_back(pItem);
152 lock.unlock();
153 m_not_full.notify_one();
154 return true;
155 1812 }
156
157 453 bool pop_remain(value_type* pItem)
158 {
159
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 453 times.
453 assert(finished);
160
1/2
✓ Branch 5 → 6 taken 453 times.
✗ Branch 5 → 7 not taken.
453 if (m_container.empty()) return false;
161 m_container.pop_back(pItem);
162 return true;
163 }
164 };
165