Developer World
Spresense SDK Library v3.2.0-ebc0364
RuntimeQue.h
1/****************************************************************************
2 * modules/include/memutils/memory_manager/RuntimeQue.h
3 *
4 * Copyright 2018 Sony Semiconductor Solutions Corporation
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * 3. Neither the name of Sony Semiconductor Solutions Corporation nor
17 * the names of its contributors may be used to endorse or promote
18 * products derived from this software without specific prior written
19 * permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ****************************************************************************/
35
36#ifndef RUNTIME_QUE_H_INCLUDED
37#define RUNTIME_QUE_H_INCLUDED
38
39#include <new> /* operator new */
40#include <stdio.h> /* printf */
41#include "memutils/common_utils/common_assert.h" /* S_ASSERT, D_ASSERT */
42#include "memutils/os_utils/cpp_util.h" /* CopyGuard */
43
44#ifdef RUNTIME_QUE_DEBUG
45/* In 64 bit environment, you need to use %zu for size_t type display. */
46
47#define DBG_P(...) printf(__VA_ARGS__)
48#else
49#define DBG_P(...)
50#endif /* RUNTIME_QUE_DEBUG */
51
52/*****************************************************************
53 * Matrix class to determine queue depth at runtime
54 *****************************************************************/
55template<typename T, /* element type */
56 typename NumT = size_t> /* element num type */
58 void post_push() { ++m_count; if (++m_put == capacity()) m_put = 0; }
59 void post_pop() { --m_count; if (++m_get == capacity()) m_get = 0; }
60
61 NumT get_index(NumT n) const {
62 return static_cast<NumT>((m_get + n < capacity()) ? m_get + n : m_get + n - capacity());
63 }
64
65public:
66 RuntimeQue(void* area, NumT depth) :
67 m_data(static_cast<T*>(area)),
68 m_capacity(depth),
69 m_put(0), m_get(0), m_count(0) {
70// D_ASSERT(que_area && depth);
71 }
72 ~RuntimeQue() { clear(); }
73
74 const void* que_area() const { return m_data; }
75 size_t elem_size() const { return sizeof(T); }
76 NumT capacity() const { return m_capacity; }
77 NumT size() const { return m_count; }
78 NumT rest() const { return static_cast<NumT>(capacity() - size()); }
79 bool empty() const { return size() == 0; }
80 bool full() const { return size() == capacity(); }
81
82 void dump() const {
83 printf("dump: put=%u, get=%u, capa=%u, size=%u, rest=%u, empty=%d, full=%d\n",
84 m_put, m_get, capacity(), size(), rest(), empty(), full());
85 for (NumT i = 0; i < size(); ++i) {
86 printf("%u: data=%08x\n",
87 i, *reinterpret_cast<const int*>(&m_data[get_index(i)]));
88 }
89 }
90
91 void clear() {
92 while (pop()) ;
93 m_put = m_get = 0;
94 }
95
96 /* Put data at the end of the queue
97 * (Use copy constructor with placement new).
98 */
99
100 bool push(const T& data) {
101 if (full()) return false;
102 ::new(&m_data[m_put]) T(data);
103 DBG_P("push: pos=%u, cnt=%u\n", m_put, m_count);
104 post_push();
105 return true;
106 }
107
108 /* Remove the data at the head of the queue after calling the destructor. */
109
110 bool pop() {
111 if (empty()) return false;
112 DBG_P("pop : pos=%u, cnt=%u\n", m_get, m_count);
113 m_data[m_get].~T();
114 post_pop();
115 return true;
116 }
117
118 /* Refer to the data at the head of the queue. */
119
120 const T& top() const { return at(0); }
121
122 /* Refer to the data of the Nth (head data is 0) of the queue. */
123
124 const T& at(NumT n) const {
125 D_ASSERT(n < m_count); /* Since an exception can not be used,
126 * it is set as assert.
127 */
128 DBG_P("at(%u): pos=%u\n", n, m_get);
129 return m_data[get_index(n)];
130 }
131
132 T& writable_at(NumT n) { return const_cast<T&>(at(n)); }
133
134 const T& front() const { return at(0); }
135 T& front() { return writable_at(0); }
136
137 const T& back() const { return at(static_cast<NumT>(m_count - 1)); }
138 T& back() { return writable_at(static_cast<NumT>(m_count - 1)); }
139
140private:
141 T* m_data; /* data area */
142 NumT m_capacity; /* queue capacity (depth) */
143 NumT m_put; /* data put position. 0 origin */
144 NumT m_get; /* data get position. 0 origin */
145 NumT m_count; /* data count in queue */
146}; /* class RuntimeQue */
147
148#undef DBG_P
149
150#endif /* RUNTIME_QUE_H_INCLUDED */
Definition: cpp_util.h:45
Definition: RuntimeQue.h:57