gem5  v20.1.0.0
circular_buffer.hh
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements. See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License. You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied. See the License for the specific language governing
16  permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 #ifndef __TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_CIRCULAR_BUFFER_HH__
21 #define __TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_CIRCULAR_BUFFER_HH__
22 
23 #include <iostream>
24 
25 namespace tlm
26 {
27 
28 template <typename T>
29 class circular_buffer
30 {
31  public:
32  explicit circular_buffer(int size=0);
34 
35  void resize(int size);
36  void clear();
37 
38  T read();
39  void write(const T &);
40 
41  bool is_empty() const { return used() == 0; }
42  bool is_full() const { return free() == 0; }
43 
44  int size() const { return m_size; }
45  int used() const { return m_used; }
46  int free() const { return m_free; }
47 
48  const T &read_data() const { return buf_read(m_buf, m_ri); }
49  const T &
50  peek_data(int i) const
51  {
52  return buf_read(m_buf, (m_ri + i) % size());
53  }
54 
55  T &
56  poke_data(int i)
57  {
58  return buf_read(m_buf, (m_wi + i) % size());
59  }
60 
61  void debug() const;
62 
63  private:
64  void increment_write_pos(int i=1);
65  void increment_read_pos(int i=1);
66 
67  void init();
68 
69  // Disabled.
70  circular_buffer(const circular_buffer<T> &b);
71  circular_buffer<T> &operator = (const circular_buffer<T> &);
72 
73  void *buf_alloc(int size);
74  void buf_free(void *&buf);
75  void buf_write(void *buf, int n, const T &t);
76  T &buf_read(void *buf, int n) const;
77  void buf_clear(void *buf, int n);
78 
79  private:
80  int m_size; // size of the buffer
81  void *m_buf; // the buffer
82  int m_free; // number of free spaces
83  int m_used; // number of used spaces
84  int m_ri; // index of next read
85  int m_wi; // index of next write
86 };
87 
88 template <typename T>
89 void
91 {
92  std::cout << "Buffer debug" << std::endl;
93  std::cout << "Size : " << size() << std::endl;
94  std::cout << "Free/Used " << free() << "/" << used() << std::endl;
95  std::cout << "Indices : r/w = " << m_ri << "/" << m_wi << std::endl;
96 
97  if (is_empty()) {
98  std::cout << "empty" << std::endl;
99  }
100 
101  if (is_full()) {
102  std::cout << "full" << std::endl;
103  }
104 
105  std::cout << "Data : " << std::endl;
106  for (int i = 0; i < used(); i++) {
107  std::cout << peek_data( i ) << std::endl;
108  }
109 }
110 
111 template <typename T>
112 circular_buffer<T>::circular_buffer(int size) : m_size(size), m_buf(0)
113 {
114  init();
115 }
116 
117 template <typename T>
118 void
120 {
121  for (int i = 0; i < used(); i++) {
122  buf_clear(m_buf, (m_ri + i) % m_size);
123  }
124  m_free = m_size;
125  m_used = m_ri = m_wi = 0;
126 }
127 
128 template <typename T>
130 {
131  clear();
132  buf_free(m_buf);
133 }
134 
135 template <typename T>
136 void
138 {
139  int i;
140  void *new_buf = buf_alloc(size);
141 
142  for (i = 0; i < size && i < used(); i++) {
143  buf_write(new_buf, i, peek_data(i));
144  buf_clear(m_buf, (m_ri + i) % m_size);
145  }
146 
147  buf_free(m_buf);
148 
149  m_size = size;
150  m_ri = 0;
151  m_wi = i % m_size;
152  m_used = i;
153  m_free = m_size - m_used;
154 
155  m_buf = new_buf;
156 }
157 
158 
159 template <typename T>
160 void
162 {
163  if (m_size > 0) {
164  m_buf = buf_alloc(m_size);
165  }
166 
167  m_free = m_size;
168  m_used = 0;
169  m_ri = 0;
170  m_wi = 0;
171 }
172 
173 template <typename T>
174 T
175 circular_buffer<T>::read()
176 {
177  T t = read_data();
178 
179  buf_clear(m_buf, m_ri);
180  increment_read_pos();
181 
182  return t;
183 }
184 
185 template <typename T>
186 void
188 {
189  buf_write(m_buf, m_wi, t);
190  increment_write_pos();
191 }
192 
193 template <typename T>
194 void
196 {
197  m_wi = (m_wi + i) % m_size;
198  m_used += i;
199  m_free -= i;
200 }
201 
202 template <typename T>
203 void
205 {
206  m_ri = (m_ri + i) % m_size;
207  m_used -= i;
208  m_free += i;
209 }
210 
211 template <typename T>
212 inline void *
214 {
215  return new unsigned char [size * sizeof(T)];
216 }
217 
218 template <typename T>
219 inline void
221 {
222  delete [] static_cast<unsigned char *>(buf);
223  buf = nullptr;
224 }
225 
226 template <typename T>
227 inline void
228 circular_buffer<T>::buf_write(void *buf, int n, const T &t)
229 {
230  T *p = static_cast<T *>(buf) + n;
231  new (p)T(t);
232 }
233 
234 template <typename T>
235 inline T &
236 circular_buffer<T>::buf_read(void *buf, int n) const
237 {
238  T *p = static_cast<T *>(buf) + n;
239  return *p;
240 }
241 
242 template <typename T>
243 inline void
244 circular_buffer<T>::buf_clear(void *buf, int n)
245 {
246  T *p = static_cast<T *>(buf) + n;
247  p->~T();
248 }
249 
250 } // namespace tlm
251 
252 #endif /* __TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_CIRCULAR_BUFFER_HH__ */
tlm::circular_buffer::read_data
const T & read_data() const
Definition: circular_buffer.hh:82
tlm::circular_buffer::buf_alloc
void * buf_alloc(int size)
Definition: circular_buffer.hh:230
Stats::init
const FlagsType init
This Stat is Initialized.
Definition: info.hh:45
tlm::circular_buffer::operator=
circular_buffer< T > & operator=(const circular_buffer< T > &)
tlm::circular_buffer::debug
void debug() const
Definition: circular_buffer.hh:107
tlm::circular_buffer::~circular_buffer
~circular_buffer()
Definition: circular_buffer.hh:146
tlm::circular_buffer::increment_read_pos
void increment_read_pos(int i=1)
Definition: circular_buffer.hh:221
tlm::circular_buffer::m_size
int m_size
Definition: circular_buffer.hh:114
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
tlm::circular_buffer::buf_write
void buf_write(void *buf, int n, const T &t)
Definition: circular_buffer.hh:245
tlm::circular_buffer::increment_write_pos
void increment_write_pos(int i=1)
Definition: circular_buffer.hh:212
tlm::circular_buffer::m_used
int m_used
Definition: circular_buffer.hh:117
tlm::circular_buffer::m_ri
int m_ri
Definition: circular_buffer.hh:118
tlm::circular_buffer::poke_data
T & poke_data(int i)
Definition: circular_buffer.hh:90
tlm::circular_buffer::free
int free() const
Definition: circular_buffer.hh:80
tlm::circular_buffer::used
int used() const
Definition: circular_buffer.hh:79
tlm::circular_buffer::m_buf
void * m_buf
Definition: circular_buffer.hh:115
ArmISA::n
Bitfield< 31 > n
Definition: miscregs_types.hh:450
tlm::circular_buffer::size
int size() const
Definition: circular_buffer.hh:78
tlm::circular_buffer::write
void write(const T &)
Definition: circular_buffer.hh:204
tlm::circular_buffer::m_free
int m_free
Definition: circular_buffer.hh:116
tlm::circular_buffer::init
void init()
Definition: circular_buffer.hh:178
tlm::circular_buffer::peek_data
const T & peek_data(int i) const
Definition: circular_buffer.hh:84
tlm::circular_buffer::is_full
bool is_full() const
Definition: circular_buffer.hh:76
tlm
Definition: analysis_fifo.hh:27
tlm::circular_buffer::buf_free
void buf_free(void *&buf)
Definition: circular_buffer.hh:237
ArmISA::b
Bitfield< 7 > b
Definition: miscregs_types.hh:376
tlm::circular_buffer::read
T read()
Definition: circular_buffer.hh:192
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
tlm::circular_buffer::clear
void clear()
Definition: circular_buffer.hh:136
tlm::circular_buffer::is_empty
bool is_empty() const
Definition: circular_buffer.hh:75
tlm::circular_buffer
Definition: circular_buffer.hh:46
tlm::circular_buffer::resize
void resize(int size)
Definition: circular_buffer.hh:154
tlm::circular_buffer::buf_clear
void buf_clear(void *buf, int n)
Definition: circular_buffer.hh:261
tlm::circular_buffer::buf_read
T & buf_read(void *buf, int n) const
Definition: circular_buffer.hh:253
tlm::circular_buffer::circular_buffer
circular_buffer(int size=0)
Definition: circular_buffer.hh:129
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
tlm::circular_buffer::m_wi
int m_wi
Definition: circular_buffer.hh:119

Generated on Wed Sep 30 2020 14:02:16 for gem5 by doxygen 1.8.17