gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
circlebuf.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Andreas Sandberg
38  */
39 
40 #ifndef __BASE_CIRCLEBUF_HH__
41 #define __BASE_CIRCLEBUF_HH__
42 
43 #include <algorithm>
44 #include <cassert>
45 #include <vector>
46 
47 #include "base/misc.hh"
48 #include "sim/serialize.hh"
49 
67 template<typename T>
68 class CircleBuf
69 {
70  public:
71  typedef T value_type;
72 
73  public:
74  explicit CircleBuf(size_t size)
75  : buf(size), _start(0), _stop(0) {}
76 
78  bool empty() const { return _stop == _start; }
83  size_t capacity() const { return buf.size(); }
85  size_t size() const { return _stop - _start; }
86 
93  void flush() {
94  _start = 0;
95  _stop = 0;
96  }
97 
104  template <class OutputIterator>
105  void peek(OutputIterator out, size_t len) const {
106  peek(out, 0, len);
107  }
108 
116  template <class OutputIterator>
117  void peek(OutputIterator out, off_t offset, size_t len) const {
118  panic_if(offset + len > size(),
119  "Trying to read past end of circular buffer.\n");
120 
121  const off_t real_start((offset + _start) % buf.size());
122  if (real_start + len <= buf.size()) {
123  std::copy(buf.begin() + real_start,
124  buf.begin() + real_start + len,
125  out);
126  } else {
127  const size_t head_size(buf.size() - real_start);
128  const size_t tail_size(len - head_size);
129  std::copy(buf.begin() + real_start, buf.end(),
130  out);
131  std::copy(buf.begin(), buf.begin() + tail_size,
132  out + head_size);
133  }
134  }
135 
142  template <class OutputIterator>
143  void read(OutputIterator out, size_t len) {
144  peek(out, len);
145 
146  _start += len;
147  normalize();
148  }
149 
156  template <class InputIterator>
157  void write(InputIterator in, size_t len) {
158  // Writes that are larger than the backing store are allowed,
159  // but only the last part of the buffer will be written.
160  if (len > buf.size()) {
161  in += len - buf.size();
162  len = buf.size();
163  }
164 
165  const size_t next(_stop % buf.size());
166  const size_t head_len(std::min(buf.size() - next, len));
167 
168  std::copy(in, in + head_len, buf.begin() + next);
169  std::copy(in + head_len, in + len, buf.begin());
170 
171  _stop += len;
172  // We may have written past the old _start pointer. Readjust
173  // the _start pointer to remove the oldest entries in that
174  // case.
175  if (size() > buf.size())
176  _start = _stop - buf.size();
177 
178  normalize();
179  }
180 
181  protected:
186  void normalize() {
187  if (_start >= buf.size()) {
188  _stop -= buf.size();
189  _start -= buf.size();
190  }
191 
192  assert(_start < buf.size());
193  assert(_stop < 2 * buf.size());
194  assert(_start <= _stop);
195  }
196 
197  protected:
199  size_t _start;
200  size_t _stop;
201 
202 };
203 
204 
216 template<typename T>
217 class Fifo
218 {
219  public:
220  typedef T value_type;
221 
222  public:
223  Fifo(size_t size)
224  : buf(size) {}
225 
226  bool empty() const { return buf.empty(); }
227  size_t size() const { return buf.size(); }
228  size_t capacity() const { return buf.capacity(); }
229 
230  void flush() { buf.flush(); }
231 
232  template <class OutputIterator>
233  void peek(OutputIterator out, size_t len) const { buf.peek(out, len); }
234  template <class OutputIterator>
235  void read(OutputIterator out, size_t len) { buf.read(out, len); }
236 
237  template <class InputIterator>
238  void write(InputIterator in, size_t len) {
239  panic_if(size() + len > capacity(),
240  "Trying to overfill FIFO buffer.\n");
241  buf.write(in, len);
242  }
243 
244  private:
246 };
247 
248 
249 template <typename T>
250 void
251 arrayParamOut(CheckpointOut &cp, const std::string &name,
252  const CircleBuf<T> &param)
253 {
254  std::vector<T> temp(param.size());
255  param.peek(temp.begin(), temp.size());
256  arrayParamOut(cp, name, temp);
257 }
258 
259 template <typename T>
260 void
261 arrayParamIn(CheckpointIn &cp, const std::string &name,
262  CircleBuf<T> &param)
263 {
264  std::vector<T> temp;
265  arrayParamIn(cp, name, temp);
266 
267  param.flush();
268  param.write(temp.cbegin(), temp.size());
269 }
270 
271 template <typename T>
272 void
273 arrayParamOut(CheckpointOut &cp, const std::string &name,
274  const Fifo<T> &param)
275 {
276  std::vector<T> temp(param.size());
277  param.peek(temp.begin(), temp.size());
278  arrayParamOut(cp, name, temp);
279 }
280 
281 template <typename T>
282 void
283 arrayParamIn(CheckpointIn &cp, const std::string &name,
284  Fifo<T> &param)
285 {
286  std::vector<T> temp;
287  arrayParamIn(cp, name, temp);
288 
289  fatal_if(param.capacity() < temp.size(),
290  "Trying to unserialize data into too small FIFO\n");
291 
292  param.flush();
293  param.write(temp.cbegin(), temp.size());
294 }
295 
296 #endif // __BASE_CIRCLEBUF_HH__
void write(InputIterator in, size_t len)
Definition: circlebuf.hh:238
size_t size() const
Return the number of elements stored in the buffer.
Definition: circlebuf.hh:85
T value_type
Definition: circlebuf.hh:71
const std::string & name()
Definition: trace.cc:49
Circular buffer backed by a vector.
Definition: circlebuf.hh:68
void normalize()
Normalize the start and stop pointers to ensure that pointer invariants hold after updates...
Definition: circlebuf.hh:186
bool empty() const
Is the buffer empty?
Definition: circlebuf.hh:78
panic_if(!root,"Invalid expression\n")
Bitfield< 23, 0 > offset
Definition: types.hh:149
T value_type
Definition: circlebuf.hh:220
bool empty() const
Definition: circlebuf.hh:226
CircleBuf(size_t size)
Definition: circlebuf.hh:74
size_t size() const
Definition: circlebuf.hh:227
CircleBuf< value_type > buf
Definition: circlebuf.hh:245
void peek(OutputIterator out, size_t len) const
Definition: circlebuf.hh:233
void write(InputIterator in, size_t len)
Add elements to the end of the ring buffers and advance.
Definition: circlebuf.hh:157
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > &param)
Definition: circlebuf.hh:251
size_t _start
Definition: circlebuf.hh:199
void peek(OutputIterator out, size_t len) const
Copy buffer contents without advancing the read pointer.
Definition: circlebuf.hh:105
void flush()
Remove all the elements in the buffer.
Definition: circlebuf.hh:93
void read(OutputIterator out, size_t len)
Copy buffer contents and advance the read pointer.
Definition: circlebuf.hh:143
size_t capacity() const
Definition: circlebuf.hh:228
Fifo(size_t size)
Definition: circlebuf.hh:223
std::ostream CheckpointOut
Definition: serialize.hh:67
std::vector< value_type > buf
Definition: circlebuf.hh:198
void peek(OutputIterator out, off_t offset, size_t len) const
Copy buffer contents without advancing the read pointer.
Definition: circlebuf.hh:117
Bitfield< 18, 16 > len
Definition: miscregs.hh:1626
size_t capacity() const
Return the maximum number of elements that can be stored in the buffer at any one time...
Definition: circlebuf.hh:83
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > &param)
Definition: circlebuf.hh:261
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
void read(OutputIterator out, size_t len)
Definition: circlebuf.hh:235
size_t _stop
Definition: circlebuf.hh:200
Simple FIFO implementation backed by a circular buffer.
Definition: circlebuf.hh:217
void flush()
Definition: circlebuf.hh:230

Generated on Fri Jun 9 2017 13:03:40 for gem5 by doxygen 1.8.6