pktfifo.hh revision 10905
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 84 protected: 85 std::list<PacketFifoEntry> fifo; 86 uint64_t _counter; 87 unsigned _maxsize; 88 unsigned _size; 89 unsigned _reserved; 90 91 public: 92 explicit PacketFifo(int max) 93 : _counter(0), _maxsize(max), _size(0), _reserved(0) {} 94 virtual ~PacketFifo() {} 95 96 unsigned packets() const { return fifo.size(); } 97 unsigned maxsize() const { return _maxsize; } 98 unsigned size() const { return _size; } 99 unsigned reserved() const { return _reserved; } 100 unsigned avail() const { return _maxsize - _size - _reserved; } 101 bool empty() const { return size() <= 0; } 102 bool full() const { return avail() <= 0; } 103 104 unsigned 105 reserve(unsigned len = 0) 106 { 107 _reserved += len; 108 assert(avail() >= 0); 109 return _reserved; 110 } 111 112 iterator begin() { return fifo.begin(); } 113 iterator end() { return fifo.end(); } 114 115 EthPacketPtr front() { return fifo.begin()->packet; } 116 117 bool push(EthPacketPtr ptr) 118 { 119 assert(ptr->length); 120 assert(_reserved <= ptr->length); 121 if (avail() < ptr->length - _reserved) 122 return false; 123 124 _size += ptr->length; 125 126 PacketFifoEntry entry; 127 entry.packet = ptr; 128 entry.number = _counter++; 129 fifo.push_back(entry); 130 _reserved = 0; 131 return true; 132 } 133 134 void pop() 135 { 136 if (empty()) 137 return; 138 139 iterator entry = fifo.begin(); 140 _size -= entry->packet->length; 141 _size -= entry->slack; 142 entry->packet = NULL; 143 fifo.pop_front(); 144 } 145 146 void clear() 147 { 148 for (iterator i = begin(); i != end(); ++i) 149 i->clear(); 150 fifo.clear(); 151 _size = 0; 152 _reserved = 0; 153 } 154 155 void remove(iterator i) 156 { 157 if (i != fifo.begin()) { 158 iterator prev = i; 159 --prev; 160 assert(prev != fifo.end()); 161 prev->slack += i->packet->length; 162 prev->slack += i->slack; 163 } else { 164 _size -= i->packet->length; 165 _size -= i->slack; 166 } 167 168 i->clear(); 169 fifo.erase(i); 170 } 171 172 bool copyout(void *dest, unsigned offset, unsigned len); 173 174 int countPacketsBefore(iterator i) 175 { 176 if (i == fifo.end()) 177 return 0; 178 return i->number - fifo.begin()->number; 179 } 180 181 int countPacketsAfter(iterator i) 182 { 183 iterator end = fifo.end(); 184 if (i == end) 185 return 0; 186 return (--end)->number - i->number; 187 } 188 189 void check() 190 { 191 unsigned total = 0; 192 for (iterator i = begin(); i != end(); ++i) 193 total += i->packet->length + i->slack; 194 195 if (total != _size) 196 panic("total (%d) is not == to size (%d)\n", total, _size); 197 } 198 199/** 200 * Serialization stuff 201 */ 202 public: 203 void serialize(const std::string &base, CheckpointOut &cp) const; 204 void unserialize(const std::string &base, CheckpointIn &cp); 205}; 206 207#endif // __DEV_PKTFIFO_HH__ 208