timebuf.hh (7813:7338bc628489) timebuf.hh (10200:1ab8753de4d8)
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 * Kevin Lim
30 */
31
32#ifndef __BASE_TIMEBUF_HH__
33#define __BASE_TIMEBUF_HH__
34
35#include <cassert>
36#include <cstring>
37#include <vector>
38
39template <class T>
40class TimeBuffer
41{
42 protected:
43 int past;
44 int future;
45 unsigned size;
46 int _id;
47
48 char *data;
49 std::vector<char *> index;
50 unsigned base;
51
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 * Kevin Lim
30 */
31
32#ifndef __BASE_TIMEBUF_HH__
33#define __BASE_TIMEBUF_HH__
34
35#include <cassert>
36#include <cstring>
37#include <vector>
38
39template <class T>
40class TimeBuffer
41{
42 protected:
43 int past;
44 int future;
45 unsigned size;
46 int _id;
47
48 char *data;
49 std::vector<char *> index;
50 unsigned base;
51
52 void valid(int idx)
52 void valid(int idx) const
53 {
54 assert (idx >= -past && idx <= future);
55 }
56
57 public:
58 friend class wire;
59 class wire
60 {
61 friend class TimeBuffer;
62 protected:
63 TimeBuffer<T> *buffer;
64 int index;
65
66 void set(int idx)
67 {
68 buffer->valid(idx);
69 index = idx;
70 }
71
72 wire(TimeBuffer<T> *buf, int i)
73 : buffer(buf), index(i)
74 { }
75
76 public:
77 wire()
78 { }
79
80 wire(const wire &i)
81 : buffer(i.buffer), index(i.index)
82 { }
83
84 const wire &operator=(const wire &i)
85 {
86 buffer = i.buffer;
87 set(i.index);
88 return *this;
89 }
90
91 const wire &operator=(int idx)
92 {
93 set(idx);
94 return *this;
95 }
96
97 const wire &operator+=(int offset)
98 {
99 set(index + offset);
100 return *this;
101 }
102
103 const wire &operator-=(int offset)
104 {
105 set(index - offset);
106 return *this;
107 }
108
109 wire &operator++()
110 {
111 set(index + 1);
112 return *this;
113 }
114
115 wire &operator++(int)
116 {
117 int i = index;
118 set(index + 1);
119 return wire(this, i);
120 }
121
122 wire &operator--()
123 {
124 set(index - 1);
125 return *this;
126 }
127
128 wire &operator--(int)
129 {
130 int i = index;
131 set(index - 1);
132 return wire(this, i);
133 }
134 T &operator*() const { return *buffer->access(index); }
135 T *operator->() const { return buffer->access(index); }
136 };
137
138
139 public:
140 TimeBuffer(int p, int f)
141 : past(p), future(f), size(past + future + 1),
142 data(new char[size * sizeof(T)]), index(size), base(0)
143 {
144 assert(past >= 0 && future >= 0);
145 char *ptr = data;
146 for (unsigned i = 0; i < size; i++) {
147 index[i] = ptr;
148 std::memset(ptr, 0, sizeof(T));
149 new (ptr) T;
150 ptr += sizeof(T);
151 }
152
153 _id = -1;
154 }
155
156 TimeBuffer()
157 : data(NULL)
158 {
159 }
160
161 ~TimeBuffer()
162 {
163 for (unsigned i = 0; i < size; ++i)
164 (reinterpret_cast<T *>(index[i]))->~T();
165 delete [] data;
166 }
167
168 void id(int id)
169 {
170 _id = id;
171 }
172
173 int id()
174 {
175 return _id;
176 }
177
178 void
179 advance()
180 {
181 if (++base >= size)
182 base = 0;
183
184 int ptr = base + future;
185 if (ptr >= (int)size)
186 ptr -= size;
187 (reinterpret_cast<T *>(index[ptr]))->~T();
188 std::memset(index[ptr], 0, sizeof(T));
189 new (index[ptr]) T;
190 }
191
53 {
54 assert (idx >= -past && idx <= future);
55 }
56
57 public:
58 friend class wire;
59 class wire
60 {
61 friend class TimeBuffer;
62 protected:
63 TimeBuffer<T> *buffer;
64 int index;
65
66 void set(int idx)
67 {
68 buffer->valid(idx);
69 index = idx;
70 }
71
72 wire(TimeBuffer<T> *buf, int i)
73 : buffer(buf), index(i)
74 { }
75
76 public:
77 wire()
78 { }
79
80 wire(const wire &i)
81 : buffer(i.buffer), index(i.index)
82 { }
83
84 const wire &operator=(const wire &i)
85 {
86 buffer = i.buffer;
87 set(i.index);
88 return *this;
89 }
90
91 const wire &operator=(int idx)
92 {
93 set(idx);
94 return *this;
95 }
96
97 const wire &operator+=(int offset)
98 {
99 set(index + offset);
100 return *this;
101 }
102
103 const wire &operator-=(int offset)
104 {
105 set(index - offset);
106 return *this;
107 }
108
109 wire &operator++()
110 {
111 set(index + 1);
112 return *this;
113 }
114
115 wire &operator++(int)
116 {
117 int i = index;
118 set(index + 1);
119 return wire(this, i);
120 }
121
122 wire &operator--()
123 {
124 set(index - 1);
125 return *this;
126 }
127
128 wire &operator--(int)
129 {
130 int i = index;
131 set(index - 1);
132 return wire(this, i);
133 }
134 T &operator*() const { return *buffer->access(index); }
135 T *operator->() const { return buffer->access(index); }
136 };
137
138
139 public:
140 TimeBuffer(int p, int f)
141 : past(p), future(f), size(past + future + 1),
142 data(new char[size * sizeof(T)]), index(size), base(0)
143 {
144 assert(past >= 0 && future >= 0);
145 char *ptr = data;
146 for (unsigned i = 0; i < size; i++) {
147 index[i] = ptr;
148 std::memset(ptr, 0, sizeof(T));
149 new (ptr) T;
150 ptr += sizeof(T);
151 }
152
153 _id = -1;
154 }
155
156 TimeBuffer()
157 : data(NULL)
158 {
159 }
160
161 ~TimeBuffer()
162 {
163 for (unsigned i = 0; i < size; ++i)
164 (reinterpret_cast<T *>(index[i]))->~T();
165 delete [] data;
166 }
167
168 void id(int id)
169 {
170 _id = id;
171 }
172
173 int id()
174 {
175 return _id;
176 }
177
178 void
179 advance()
180 {
181 if (++base >= size)
182 base = 0;
183
184 int ptr = base + future;
185 if (ptr >= (int)size)
186 ptr -= size;
187 (reinterpret_cast<T *>(index[ptr]))->~T();
188 std::memset(index[ptr], 0, sizeof(T));
189 new (index[ptr]) T;
190 }
191
192 T *access(int idx)
192 protected:
193 //Calculate the index into this->index for element at position idx
194 //relative to now
195 inline int calculateVectorIndex(int idx) const
193 {
194 //Need more complex math here to calculate index.
195 valid(idx);
196
197 int vector_index = idx + base;
198 if (vector_index >= (int)size) {
199 vector_index -= size;
200 } else if (vector_index < 0) {
201 vector_index += size;
202 }
203
196 {
197 //Need more complex math here to calculate index.
198 valid(idx);
199
200 int vector_index = idx + base;
201 if (vector_index >= (int)size) {
202 vector_index -= size;
203 } else if (vector_index < 0) {
204 vector_index += size;
205 }
206
207 return vector_index;
208 }
209
210 public:
211 T *access(int idx)
212 {
213 int vector_index = calculateVectorIndex(idx);
214
204 return reinterpret_cast<T *>(index[vector_index]);
205 }
206
207 T &operator[](int idx)
208 {
215 return reinterpret_cast<T *>(index[vector_index]);
216 }
217
218 T &operator[](int idx)
219 {
209 //Need more complex math here to calculate index.
210 valid(idx);
220 int vector_index = calculateVectorIndex(idx);
211
221
212 int vector_index = idx + base;
213 if (vector_index >= (int)size) {
214 vector_index -= size;
215 } else if (vector_index < 0) {
216 vector_index += size;
217 }
218
219 return reinterpret_cast<T &>(*index[vector_index]);
220 }
221
222 return reinterpret_cast<T &>(*index[vector_index]);
223 }
224
225 const T &operator[] (int idx) const
226 {
227 int vector_index = calculateVectorIndex(idx);
228
229 return reinterpret_cast<const T &>(*index[vector_index]);
230 }
231
222 wire getWire(int idx)
223 {
224 valid(idx);
225
226 return wire(this, idx);
227 }
228
229 wire zero()
230 {
231 return wire(this, 0);
232 }
233
234 unsigned getSize()
235 {
236 return size;
237 }
238};
239
240#endif // __BASE_TIMEBUF_HH__
241
232 wire getWire(int idx)
233 {
234 valid(idx);
235
236 return wire(this, idx);
237 }
238
239 wire zero()
240 {
241 return wire(this, 0);
242 }
243
244 unsigned getSize()
245 {
246 return size;
247 }
248};
249
250#endif // __BASE_TIMEBUF_HH__
251