pktfifo.hh revision 11006
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, CheckpointOut &cp) const; 74 void unserialize(const std::string &base, CheckpointIn &cp); 75}; 76 77class PacketFifo 78{ 79 public: 80 81 typedef std::list<PacketFifoEntry> fifo_list; 82 typedef fifo_list::iterator iterator; 83 typedef fifo_list::const_iterator const_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 const_iterator begin() const { return fifo.begin(); } 117 const_iterator end() const { return fifo.end(); } 118 119 EthPacketPtr front() { return fifo.begin()->packet; } 120 121 bool push(EthPacketPtr ptr) 122 { 123 assert(ptr->length); 124 assert(_reserved <= ptr->length); 125 if (avail() < ptr->length - _reserved) 126 return false; 127 128 _size += ptr->length; 129 130 PacketFifoEntry entry; 131 entry.packet = ptr; 132 entry.number = _counter++; 133 fifo.push_back(entry); 134 _reserved = 0; 135 return true; 136 } 137 138 void pop() 139 { 140 if (empty()) 141 return; 142 143 iterator entry = fifo.begin(); 144 _size -= entry->packet->length; 145 _size -= entry->slack; 146 entry->packet = NULL; 147 fifo.pop_front(); 148 } 149 150 void clear() 151 { 152 for (iterator i = begin(); i != end(); ++i) 153 i->clear(); 154 fifo.clear(); 155 _size = 0; 156 _reserved = 0; 157 } 158 159 void remove(iterator i) 160 { 161 if (i != fifo.begin()) { 162 iterator prev = i; 163 --prev; 164 assert(prev != fifo.end()); 165 prev->slack += i->packet->length; 166 prev->slack += i->slack; 167 } else { 168 _size -= i->packet->length; 169 _size -= i->slack; 170 } 171 172 i->clear(); 173 fifo.erase(i); 174 } 175 176 bool copyout(void *dest, unsigned offset, unsigned len); 177 178 int countPacketsBefore(const_iterator i) const 179 { 180 if (i == fifo.end()) 181 return 0; 182 return i->number - fifo.begin()->number; 183 } 184 185 int countPacketsAfter(const_iterator i) const 186 { 187 auto end = fifo.end(); 188 if (i == end) 189 return 0; 190 return (--end)->number - i->number; 191 } 192 193 void check() const 194 { 195 unsigned total = 0; 196 for (auto i = begin(); i != end(); ++i) 197 total += i->packet->length + i->slack; 198 199 if (total != _size) 200 panic("total (%d) is not == to size (%d)\n", total, _size); 201 } 202 203/** 204 * Serialization stuff 205 */ 206 public: 207 void serialize(const std::string &base, CheckpointOut &cp) const; 208 void unserialize(const std::string &base, CheckpointIn &cp); 209}; 210 211#endif // __DEV_PKTFIFO_HH__ 212