gem5  v22.1.0.0
circlebuf.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015,2017-2018 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 
38 #ifndef __BASE_CIRCLEBUF_HH__
39 #define __BASE_CIRCLEBUF_HH__
40 
41 #include <algorithm>
42 #include <cassert>
43 #include <iterator>
44 #include <vector>
45 
46 #include "base/logging.hh"
47 #include "sim/serialize.hh"
48 
49 namespace gem5
50 {
51 
57 template<typename T>
58 class CircleBuf
59 {
60  private:
62  size_t start = 0;
63  size_t used = 0;
64  size_t maxSize;
65 
66  public:
67  using value_type = T;
68 
69  explicit CircleBuf(size_t size) : buffer(size), maxSize(size) {}
70 
71  bool empty() const { return used == 0; }
72  size_t size() const { return used; }
73  size_t capacity() const { return maxSize; }
74 
78  void
80  {
81  start = 0;
82  used = 0;
83  }
84 
91  template <class OutputIterator>
92  void
93  peek(OutputIterator out, size_t len) const
94  {
95  peek(out, 0, len);
96  }
97 
105  template <class OutputIterator>
106  void
107  peek(OutputIterator out, off_t offset, size_t len) const
108  {
109  panic_if(offset + len > used,
110  "Trying to read past end of circular buffer.");
111 
112  if (!len)
113  return;
114 
115  // The iterator for the next byte to copy out.
116  auto next_it = buffer.begin() + (start + offset) % maxSize;
117  // How much there is to copy from until the end of the buffer.
118  const size_t to_end = buffer.end() - next_it;
119 
120  // If the data to be copied wraps, take care of the first part.
121  if (to_end < len) {
122  // Copy it.
123  out = std::copy_n(next_it, to_end, out);
124  // Start copying again at the start of buffer.
125  next_it = buffer.begin();
126  len -= to_end;
127  }
128  // Copy the remaining (or only) chunk of data.
129  std::copy_n(next_it, len, out);
130  }
131 
138  template <class OutputIterator>
139  void
140  read(OutputIterator out, size_t len)
141  {
142  peek(out, len);
143  used -= len;
144  start += len;
145  }
146 
156  template <class InputIterator>
157  void
158  write(InputIterator in, size_t len)
159  {
160  if (!len)
161  return;
162 
163  // Writes that are larger than the buffer size are allowed, but only
164  // the last part of the date will be written since the rest will be
165  // overwritten and not remain in the buffer.
166  if (len > maxSize) {
167  in += len - maxSize;
168  flush();
169  len = maxSize;
170  }
171 
172  // How much existing data will be overwritten?
173  const size_t total_bytes = used + len;
174  const size_t overflow = total_bytes > maxSize ?
175  total_bytes - maxSize : 0;
176  // The iterator of the next byte to add.
177  auto next_it = buffer.begin() + (start + used) % maxSize;
178  // How much there is to copy to the end of the buffer.
179  const size_t to_end = buffer.end() - next_it;
180 
181  // If this addition wraps, take care of the first part here.
182  if (to_end < len) {
183  // Copy it.
184  std::copy_n(in, to_end, next_it);
185  // Update state to reflect what's left.
186  next_it = buffer.begin();
187  std::advance(in, to_end);
188  len -= to_end;
189  used += to_end;
190  }
191  // Copy the remaining (or only) chunk of data.
192  std::copy_n(in, len, next_it);
193  used += len;
194 
195  // Don't count data that was overwritten.
196  used -= overflow;
197  start += overflow;
198  }
199 };
200 
212 template<typename T>
213 class Fifo
214 {
215  public:
216  typedef T value_type;
217 
218  public:
219  Fifo(size_t size) : buf(size) {}
220 
221  bool empty() const { return buf.empty(); }
222  size_t size() const { return buf.size(); }
223  size_t capacity() const { return buf.capacity(); }
224 
225  void flush() { buf.flush(); }
226 
227  template <class OutputIterator>
228  void peek(OutputIterator out, size_t len) const { buf.peek(out, len); }
229  template <class OutputIterator>
230  void read(OutputIterator out, size_t len) { buf.read(out, len); }
231 
232  template <class InputIterator>
233  void
234  write(InputIterator in, size_t len)
235  {
236  panic_if(size() + len > capacity(), "Trying to overfill FIFO buffer.");
237  buf.write(in, len);
238  }
239 
240  private:
242 };
243 
244 
245 template <typename T>
246 void
247 arrayParamOut(CheckpointOut &cp, const std::string &name,
248  const CircleBuf<T> &param)
249 {
250  std::vector<T> temp(param.size());
251  param.peek(temp.begin(), temp.size());
252  arrayParamOut(cp, name, temp);
253 }
254 
255 template <typename T>
256 void
257 arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf<T> &param)
258 {
259  std::vector<T> temp;
260  arrayParamIn(cp, name, temp);
261 
262  param.flush();
263  param.write(temp.cbegin(), temp.size());
264 }
265 
266 template <typename T>
267 void
268 arrayParamOut(CheckpointOut &cp, const std::string &name, const Fifo<T> &param)
269 {
270  std::vector<T> temp(param.size());
271  param.peek(temp.begin(), temp.size());
272  arrayParamOut(cp, name, temp);
273 }
274 
275 template <typename T>
276 void
277 arrayParamIn(CheckpointIn &cp, const std::string &name, Fifo<T> &param)
278 {
279  std::vector<T> temp;
280  arrayParamIn(cp, name, temp);
281 
282  fatal_if(param.capacity() < temp.size(),
283  "Trying to unserialize data into too small FIFO");
284 
285  param.flush();
286  param.write(temp.cbegin(), temp.size());
287 }
288 
289 } // namespace gem5
290 
291 #endif // __BASE_CIRCLEBUF_HH__
Circular buffer backed by a vector.
Definition: circlebuf.hh:59
std::vector< T > buffer
Definition: circlebuf.hh:61
CircleBuf(size_t size)
Definition: circlebuf.hh:69
size_t size() const
Definition: circlebuf.hh:72
void read(OutputIterator out, size_t len)
Copy buffer contents and advance the read pointer.
Definition: circlebuf.hh:140
void write(InputIterator in, size_t len)
Add elements to the end of the ring buffers and advance.
Definition: circlebuf.hh:158
bool empty() const
Definition: circlebuf.hh:71
void peek(OutputIterator out, off_t offset, size_t len) const
Copy buffer contents without advancing the read pointer.
Definition: circlebuf.hh:107
size_t capacity() const
Definition: circlebuf.hh:73
void flush()
Throw away any data in the buffer.
Definition: circlebuf.hh:79
void peek(OutputIterator out, size_t len) const
Copy buffer contents without advancing the read pointer.
Definition: circlebuf.hh:93
size_t maxSize
Definition: circlebuf.hh:64
Simple FIFO implementation backed by a circular buffer.
Definition: circlebuf.hh:214
void write(InputIterator in, size_t len)
Definition: circlebuf.hh:234
void peek(OutputIterator out, size_t len) const
Definition: circlebuf.hh:228
void flush()
Definition: circlebuf.hh:225
size_t capacity() const
Definition: circlebuf.hh:223
CircleBuf< value_type > buf
Definition: circlebuf.hh:241
size_t size() const
Definition: circlebuf.hh:222
Fifo(size_t size)
Definition: circlebuf.hh:219
bool empty() const
Definition: circlebuf.hh:221
void read(OutputIterator out, size_t len)
Definition: circlebuf.hh:230
STL vector class.
Definition: stl.hh:37
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
decltype(std::begin(std::declval< const T & >()), std::end(std::declval< const T & >()), void()) arrayParamOut(CheckpointOut &os, const std::string &name, const T &param)
Definition: serialize.hh:409
uint16_t len
Definition: helpers.cc:62
Bitfield< 23, 0 > offset
Definition: types.hh:144
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::ostream CheckpointOut
Definition: serialize.hh:66
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > &param)
Definition: circlebuf.hh:257
static void overflow(double &c, const scfx_params &params, bool &o_flag)
Definition: sc_fxnum.cc:428
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:28 for gem5 by doxygen 1.9.1