gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
25namespace tlm
26{
27
28template <typename T>
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.
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
88template <typename T>
89void
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
111template <typename T>
112circular_buffer<T>::circular_buffer(int size) : m_size(size), m_buf(0)
113{
114 init();
115}
116
117template <typename T>
118void
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
128template <typename T>
130{
131 clear();
132 buf_free(m_buf);
133}
134
135template <typename T>
136void
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
159template <typename T>
160void
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
173template <typename T>
174T
176{
177 T t = read_data();
178
179 buf_clear(m_buf, m_ri);
180 increment_read_pos();
181
182 return t;
183}
184
185template <typename T>
186void
188{
189 buf_write(m_buf, m_wi, t);
190 increment_write_pos();
191}
192
193template <typename T>
194void
196{
197 m_wi = (m_wi + i) % m_size;
198 m_used += i;
199 m_free -= i;
200}
201
202template <typename T>
203void
205{
206 m_ri = (m_ri + i) % m_size;
207 m_used -= i;
208 m_free += i;
209}
210
211template <typename T>
212inline void *
214{
215 return new unsigned char [size * sizeof(T)];
216}
217
218template <typename T>
219inline void
221{
222 delete [] static_cast<unsigned char *>(buf);
223 buf = nullptr;
224}
225
226template <typename T>
227inline void
228circular_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
234template <typename T>
235inline T &
236circular_buffer<T>::buf_read(void *buf, int n) const
237{
238 T *p = static_cast<T *>(buf) + n;
239 return *p;
240}
241
242template <typename T>
243inline void
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__ */
void buf_write(void *buf, int n, const T &t)
circular_buffer(const circular_buffer< T > &b)
void buf_free(void *&buf)
void increment_write_pos(int i=1)
T & buf_read(void *buf, int n) const
circular_buffer< T > & operator=(const circular_buffer< T > &)
const T & read_data() const
void increment_read_pos(int i=1)
const T & peek_data(int i) const
void buf_clear(void *buf, int n)
void * buf_alloc(int size)
SwitchingFiber b

Generated on Tue Jun 18 2024 16:24:07 for gem5 by doxygen 1.11.0