Merge zizzer:/z/m5/Bitkeeper/newmem
[gem5.git] / src / base / timebuf.hh
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 <vector>
36
37 template <class T>
38 class TimeBuffer
39 {
40 protected:
41 int past;
42 int future;
43 int size;
44
45 char *data;
46 std::vector<char *> index;
47 int base;
48
49 void valid(int idx)
50 {
51 assert (idx >= -past && idx <= future);
52 }
53
54 public:
55 friend class wire;
56 class wire
57 {
58 friend class TimeBuffer;
59 protected:
60 TimeBuffer<T> *buffer;
61 int index;
62
63 void set(int idx)
64 {
65 buffer->valid(idx);
66 index = idx;
67 }
68
69 wire(TimeBuffer<T> *buf, int i)
70 : buffer(buf), index(i)
71 { }
72
73 public:
74 wire()
75 { }
76
77 wire(const wire &i)
78 : buffer(i.buffer), index(i.index)
79 { }
80
81 const wire &operator=(const wire &i)
82 {
83 buffer = i.buffer;
84 set(i.index);
85 return *this;
86 }
87
88 const wire &operator=(int idx)
89 {
90 set(idx);
91 return *this;
92 }
93
94 const wire &operator+=(int offset)
95 {
96 set(index + offset);
97 return *this;
98 }
99
100 const wire &operator-=(int offset)
101 {
102 set(index - offset);
103 return *this;
104 }
105
106 wire &operator++()
107 {
108 set(index + 1);
109 return *this;
110 }
111
112 wire &operator++(int)
113 {
114 int i = index;
115 set(index + 1);
116 return wire(this, i);
117 }
118
119 wire &operator--()
120 {
121 set(index - 1);
122 return *this;
123 }
124
125 wire &operator--(int)
126 {
127 int i = index;
128 set(index - 1);
129 return wire(this, i);
130 }
131 T &operator*() const { return *buffer->access(index); }
132 T *operator->() const { return buffer->access(index); }
133 };
134
135
136 public:
137 TimeBuffer(int p, int f)
138 : past(p), future(f), size(past + future + 1),
139 data(new char[size * sizeof(T)]), index(size), base(0)
140 {
141 assert(past >= 0 && future >= 0);
142 char *ptr = data;
143 for (int i = 0; i < size; i++) {
144 index[i] = ptr;
145 memset(ptr, 0, sizeof(T));
146 new (ptr) T;
147 ptr += sizeof(T);
148 }
149 }
150
151 TimeBuffer()
152 : data(NULL)
153 {
154 }
155
156 ~TimeBuffer()
157 {
158 for (int i = 0; i < size; ++i)
159 (reinterpret_cast<T *>(index[i]))->~T();
160 delete [] data;
161 }
162
163 void
164 advance()
165 {
166 if (++base >= size)
167 base = 0;
168
169 int ptr = base + future;
170 if (ptr >= size)
171 ptr -= size;
172 (reinterpret_cast<T *>(index[ptr]))->~T();
173 memset(index[ptr], 0, sizeof(T));
174 new (index[ptr]) T;
175 }
176
177 T *access(int idx)
178 {
179 //Need more complex math here to calculate index.
180 valid(idx);
181
182 int vector_index = idx + base;
183 if (vector_index >= size) {
184 vector_index -= size;
185 } else if (vector_index < 0) {
186 vector_index += size;
187 }
188
189 return reinterpret_cast<T *>(index[vector_index]);
190 }
191
192 T &operator[](int idx)
193 {
194 //Need more complex math here to calculate index.
195 valid(idx);
196
197 int vector_index = idx + base;
198 if (vector_index >= size) {
199 vector_index -= size;
200 } else if (vector_index < 0) {
201 vector_index += size;
202 }
203
204 return reinterpret_cast<T &>(*index[vector_index]);
205 }
206
207 wire getWire(int idx)
208 {
209 valid(idx);
210
211 return wire(this, idx);
212 }
213
214 wire zero()
215 {
216 return wire(this, 0);
217 }
218
219 int getSize()
220 {
221 return size;
222 }
223 };
224
225 #endif // __BASE_TIMEBUF_HH__
226