pktfifo.hh revision 6227
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 */ 30 31#ifndef __DEV_PKTFIFO_HH__ 32#define __DEV_PKTFIFO_HH__ 33 34#include <iosfwd> 35#include <list> 36#include <string> 37 38#include "dev/etherpkt.hh" 39#include "sim/serialize.hh" 40 41class Checkpoint; 42 43struct PacketFifoEntry 44{ 45 EthPacketPtr packet; 46 uint64_t number; 47 unsigned slack; 48 int priv; 49 50 PacketFifoEntry() 51 { 52 clear(); 53 } 54 55 PacketFifoEntry(const PacketFifoEntry &s) 56 : packet(s.packet), number(s.number), slack(s.slack), priv(s.priv) 57 { 58 } 59 60 PacketFifoEntry(EthPacketPtr p, uint64_t n) 61 : packet(p), number(n), slack(0), priv(-1) 62 { 63 } 64 65 void clear() 66 { 67 packet = NULL; 68 number = 0; 69 slack = 0; 70 priv = -1; 71 } 72 73 void serialize(const std::string &base, std::ostream &os); 74 void unserialize(const std::string &base, Checkpoint *cp, 75 const std::string §ion); 76}; 77 78class PacketFifo 79{ 80 public: 81 82 typedef std::list<PacketFifoEntry> fifo_list; 83 typedef fifo_list::iterator iterator; 84 85 protected: 86 std::list<PacketFifoEntry> fifo; 87 uint64_t _counter; 88 unsigned _maxsize; 89 unsigned _size; 90 unsigned _reserved; 91 92 public: 93 explicit PacketFifo(int max) 94 : _counter(0), _maxsize(max), _size(0), _reserved(0) {} 95 virtual ~PacketFifo() {} 96 97 unsigned packets() const { return fifo.size(); } 98 unsigned maxsize() const { return _maxsize; } 99 unsigned size() const { return _size; } 100 unsigned reserved() const { return _reserved; } 101 unsigned avail() const { return _maxsize - _size - _reserved; } 102 bool empty() const { return size() <= 0; } 103 bool full() const { return avail() <= 0; } 104 105 unsigned 106 reserve(unsigned len = 0) 107 { 108 _reserved += len; 109 assert(avail() >= 0); 110 return _reserved; 111 } 112 113 iterator begin() { return fifo.begin(); } 114 iterator end() { return fifo.end(); } 115 116 EthPacketPtr front() { return fifo.begin()->packet; } 117 118 bool push(EthPacketPtr ptr) 119 { 120 assert(ptr->length); 121 assert(_reserved <= ptr->length); 122 if (avail() < ptr->length - _reserved) 123 return false; 124 125 _size += ptr->length; 126 127 PacketFifoEntry entry; 128 entry.packet = ptr; 129 entry.number = _counter++; 130 fifo.push_back(entry); 131 _reserved = 0; 132 return true; 133 } 134 135 void pop() 136 { 137 if (empty()) 138 return; 139 140 iterator entry = fifo.begin(); 141 _size -= entry->packet->length; 142 _size -= entry->slack; 143 entry->packet = NULL; 144 fifo.pop_front(); 145 } 146 147 void clear() 148 { 149 for (iterator i = begin(); i != end(); ++i) 150 i->clear(); 151 fifo.clear(); 152 _size = 0; 153 _reserved = 0; 154 } 155 156 void remove(iterator i) 157 { 158 if (i != fifo.begin()) { 159 iterator prev = i; 160 --prev; 161 assert(prev != fifo.end()); 162 prev->slack += i->packet->length; 163 prev->slack += i->slack; 164 } else { 165 _size -= i->packet->length; 166 _size -= i->slack; 167 } 168 169 i->clear(); 170 fifo.erase(i); 171 } 172 173 bool copyout(void *dest, unsigned offset, unsigned len); 174 175 int countPacketsBefore(iterator i) 176 { 177 if (i == fifo.end()) 178 return 0; 179 return i->number - fifo.begin()->number; 180 } 181 182 int countPacketsAfter(iterator i) 183 { 184 iterator end = fifo.end(); 185 if (i == end) 186 return 0; 187 return (--end)->number - i->number; 188 } 189 190 void check() 191 { 192 unsigned total = 0; 193 for (iterator i = begin(); i != end(); ++i) 194 total += i->packet->length + i->slack; 195 196 if (total != _size) 197 panic("total (%d) is not == to size (%d)\n", total, _size); 198 } 199 200/** 201 * Serialization stuff 202 */ 203 public: 204 void serialize(const std::string &base, std::ostream &os); 205 void unserialize(const std::string &base, 206 Checkpoint *cp, const std::string §ion); 207}; 208 209#endif // __DEV_PKTFIFO_HH__ 210