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