36#ifndef BASIC_QUEUE_H_INCLUDED
37#define BASIC_QUEUE_H_INCLUDED
42#include "memutils/common_utils/common_types.h"
43#include "memutils/common_utils/common_assert.h"
44#include "memutils/os_utils/cpp_util.h"
45#include "memutils/message/AssertInfo.h"
51#define DRM_TO_CACHED_VA(drm) (void*)(drm)
63 enum { init_value = 0 };
67 enum { init_value = INVALID_DRM };
73template<
typename AddrT,
76 uint8_t FillAfterPop = 0x00>
83 m_elem_size(0), m_capacity(0),
84 m_put(0), m_get(0), m_count(0) {}
86 BasicQueue(AddrT data_area, SizeT elem, NumT num) :
87 m_data_area(data_area), m_elem_size(elem), m_capacity(num),
88 m_put(0), m_get(0), m_count(0) {
98 void init(AddrT data_area, SizeT elem, NumT num) {
100 D_ASSERT(is_init() ==
false);
101 m_data_area = data_area;
107 SizeT elem_size()
const {
return m_elem_size; }
108 NumT capacity()
const {
return m_capacity; }
109 NumT size()
const {
return m_count; }
110 NumT rest()
const {
return static_cast<NumT
>(capacity() - size()); }
111 bool empty()
const {
return size() == 0; }
112 bool full()
const {
return size() == capacity(); }
115 printf(
"dump: put=%u, get=%u, capa=%u, elem=%u, size=%u, rest=%u, empty=%d, full=%d\n",
116 m_put, m_get, capacity(), elem_size(), size(), rest(), empty(), full());
117 printf(
" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
118 for (NumT i = 0; i < capacity(); ++i) {
120 for (NumT j = 0; j < MIN(elem_size(), 16); ++j) {
121 printf(
"%02x ",
static_cast<uint8_t*
>(getAddr(i))[j]);
127 void dump_active()
const {
128 printf(
"dump: size=%u, rest=%u\n", size(), rest());
129 printf(
" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
130 for (NumT i = 0; i < size(); ++i) {
132 for (NumT j = 0; j < MIN(elem_size(), 16); ++j) {
133 printf(
"%02x ",
static_cast<uint8_t*
>(getAddr(getIndex(i)))[j]);
148 bool push(
const void* data, SizeT len) {
149 D_ASSERT2(len <= elem_size(),
AssertParamLog(AssertIdSizeError, len, elem_size()));
150 if (full())
return false;
151 memcpy(getAddr(m_put), data, len);
159 bool push(
const T& data) {
160 D_ASSERT2(
sizeof(T) <= elem_size(),
AssertParamLog(AssertIdSizeError,
sizeof(T), elem_size()));
161 if (full())
return false;
162 ::new(getAddr(m_put)) T(data);
170 if (empty())
return false;
179 D_ASSERT2(
sizeof(T) <= elem_size(),
AssertParamLog(AssertIdSizeError,
sizeof(T), elem_size()));
180 if (empty())
return false;
181 static_cast<T*
>(getAddr(m_get))->~T();
189 const T& top()
const {
return at<T>(0); }
194 const T& at(NumT n)
const {
195 D_ASSERT2(
sizeof(T) <= elem_size(),
AssertParamLog(AssertIdSizeError,
sizeof(T), elem_size()));
196 D_ASSERT2(n < m_count,
AssertParamLog(AssertIdBadParam, n, m_count));
197 return *
static_cast<T*
>(getAddr(getIndex(n)));
201 T& writable_at(NumT n) {
return const_cast<T&
>(at<T>(n)); }
206 const T& front()
const {
return at<T>(0); }
209 T& front() {
return writable_at<T>(0); }
214 const T& back()
const {
return at<T>(
static_cast<NumT
>(m_count - 1)); }
217 T& back() {
return writable_at<T>(
static_cast<NumT
>(m_count - 1)); }
222 if (++m_put == capacity()) {
229 memset(getAddr(m_get), FillAfterPop, elem_size());
232 if (++m_get == capacity()) {
237 NumT getIndex(NumT n)
const {
238 return static_cast<NumT
>((m_get + n < capacity()) ? m_get + n : m_get + n - capacity());
243 void* getAddr(NumT n)
const {
return getAddr(n, AddrT()); }
245 void* getAddr(NumT n, drm_t )
const {
246 return static_cast<uint8_t*
>(DRM_TO_CACHED_VA(m_data_area)) + n * elem_size();
249 void* getAddr(NumT n,
void* )
const {
250 return static_cast<uint8_t*
>(m_data_area) + n * elem_size();
263#ifdef TEST_BASIC_QUEUE
270static void testQueOperation(TestQue& que)
272 for (uint32_t i = 0; i <= que.capacity(); ++i) {
275 F_ASSERT(que.size() == i);
276 F_ASSERT(que.rest() == que.capacity() - i);
277 F_ASSERT(que.empty() == (i == 0));
278 F_ASSERT(que.full() == (i == que.capacity()));
280 uint32_t n =
'a' + i;
282 F_ASSERT(que.push(n) == (i < que.capacity()));
284 F_ASSERT(que.push(&n,
sizeof(n)) == (i < que.capacity()));
286 F_ASSERT(que.top<uint32_t>() ==
'a');
287 F_ASSERT(que.front<uint32_t>() ==
'a');
288 F_ASSERT(que.back<uint32_t>() ==
static_cast<uint32_t
>(
'a' + MIN(i,
static_cast<uint32_t
>(que.capacity() - 1))));
292 for (uint32_t i = 0; i <= que.capacity(); ++i) {
293 F_ASSERT(que.size() == que.capacity() - i);
294 F_ASSERT(que.rest() == i);
295 F_ASSERT(que.empty() == (i == que.capacity()));
296 F_ASSERT(que.full() == (i == 0));
299 F_ASSERT(que.pop() == (i < que.capacity()));
301 F_ASSERT(que.pop<uint32_t>() == (i < que.capacity()));
303 if (i <
static_cast<uint32_t
>(que.capacity() - 1)) {
304 F_ASSERT(que.top<uint32_t>() ==
'b' + i);
305 F_ASSERT(que.front<uint32_t>() ==
'b' + i);
306 F_ASSERT(que.back<uint32_t>() ==
static_cast<uint32_t
>(
'a' + que.capacity() - 1));
315 printf(
"Start TestBasicQueue()\n");
317 const uint32_t QueElemSize = 64;
318 const uint32_t QueElemNum = 16;
319 static uint8_t s_queue_data[QueElemSize * QueElemNum];
323 F_ASSERT(que.is_init() ==
false);
324 que.init(s_queue_data, QueElemSize, QueElemNum);
325 F_ASSERT(que.is_init());
326 F_ASSERT(que.elem_size() == QueElemSize);
327 F_ASSERT(que.capacity() == QueElemNum);
328 testQueOperation(que);
332 TestQue que(s_queue_data, QueElemSize, QueElemNum);
333 F_ASSERT(que.is_init());
334 F_ASSERT(que.elem_size() == QueElemSize);
335 F_ASSERT(que.capacity() == QueElemNum);
336 testQueOperation(que);
340 printf(
"End TestBasicQueue()\n");
Definition: BasicQueue.h:79
Definition: cpp_util.h:45
Definition: AssertInfo.h:210
Definition: BasicQueue.h:56