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