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