pktfifo.hh revision 11006
12SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Nathan Binkert 292665SN/A */ 302SN/A 312SN/A#ifndef __DEV_PKTFIFO_HH__ 321400SN/A#define __DEV_PKTFIFO_HH__ 331400SN/A 342SN/A#include <iosfwd> 351298SN/A#include <list> 361298SN/A#include <string> 378229Snate@binkert.org 381298SN/A#include "dev/etherpkt.hh" 398229Snate@binkert.org#include "sim/serialize.hh" 408229Snate@binkert.org 418853Sandreas.hansson@arm.comclass Checkpoint; 425034SN/A 431400SN/Astruct PacketFifoEntry 441400SN/A{ 451298SN/A EthPacketPtr packet; 46695SN/A uint64_t number; 472SN/A unsigned slack; 483187SN/A int priv; 493187SN/A 502SN/A PacketFifoEntry() 512SN/A { 525034SN/A clear(); 535034SN/A } 542SN/A 553187SN/A PacketFifoEntry(const PacketFifoEntry &s) 563187SN/A : packet(s.packet), number(s.number), slack(s.slack), priv(s.priv) 572SN/A { 582SN/A } 591634SN/A 605100SN/A PacketFifoEntry(EthPacketPtr p, uint64_t n) 611634SN/A : packet(p), number(n), slack(0), priv(-1) 622SN/A { 632SN/A } 642SN/A 658922Swilliam.wang@arm.com void clear() 668922Swilliam.wang@arm.com { 673187SN/A packet = NULL; 685315SN/A number = 0; 695315SN/A slack = 0; 705315SN/A priv = -1; 715315SN/A } 725314SN/A 735314SN/A void serialize(const std::string &base, CheckpointOut &cp) const; 742SN/A void unserialize(const std::string &base, CheckpointIn &cp); 752SN/A}; 762SN/A 772SN/Aclass PacketFifo 782SN/A{ 795606SN/A public: 802SN/A 815606SN/A typedef std::list<PacketFifoEntry> fifo_list; 825606SN/A typedef fifo_list::iterator iterator; 835336SN/A typedef fifo_list::const_iterator const_iterator; 842SN/A 852SN/A protected: 862SN/A std::list<PacketFifoEntry> fifo; 874474SN/A uint64_t _counter; 888922Swilliam.wang@arm.com unsigned _maxsize; 893187SN/A unsigned _size; 903187SN/A unsigned _reserved; 913187SN/A 923187SN/A public: 933187SN/A explicit PacketFifo(int max) 943187SN/A : _counter(0), _maxsize(max), _size(0), _reserved(0) {} 958922Swilliam.wang@arm.com virtual ~PacketFifo() {} 963187SN/A 973187SN/A unsigned packets() const { return fifo.size(); } 983187SN/A unsigned maxsize() const { return _maxsize; } 993187SN/A unsigned size() const { return _size; } 1003349SN/A unsigned reserved() const { return _reserved; } 1013187SN/A unsigned avail() const { return _maxsize - _size - _reserved; } 1028948Sandreas.hansson@arm.com bool empty() const { return size() <= 0; } 1033187SN/A bool full() const { return avail() <= 0; } 1048948Sandreas.hansson@arm.com 1058948Sandreas.hansson@arm.com unsigned 1068948Sandreas.hansson@arm.com reserve(unsigned len = 0) 1073187SN/A { 1083187SN/A _reserved += len; 1093187SN/A assert(avail() >= 0); 1103187SN/A return _reserved; 1113187SN/A } 1123187SN/A 1138853Sandreas.hansson@arm.com iterator begin() { return fifo.begin(); } 1143187SN/A iterator end() { return fifo.end(); } 1155386SN/A 1163187SN/A const_iterator begin() const { return fifo.begin(); } 1173187SN/A const_iterator end() const { return fifo.end(); } 1183187SN/A 1193187SN/A EthPacketPtr front() { return fifo.begin()->packet; } 1203187SN/A 1213187SN/A bool push(EthPacketPtr ptr) 1223187SN/A { 1233187SN/A assert(ptr->length); 1243187SN/A assert(_reserved <= ptr->length); 1253187SN/A if (avail() < ptr->length - _reserved) 1263187SN/A return false; 1273349SN/A 1283187SN/A _size += ptr->length; 1293187SN/A 1307544SN/A PacketFifoEntry entry; 1317544SN/A entry.packet = ptr; 1327544SN/A entry.number = _counter++; 1337544SN/A fifo.push_back(entry); 1347544SN/A _reserved = 0; 1352SN/A return true; 1365543SN/A } 1372SN/A 1385543SN/A void pop() 1395543SN/A { 1402SN/A if (empty()) 1412SN/A return; 1427544SN/A 1437544SN/A iterator entry = fifo.begin(); 1448832SAli.Saidi@ARM.com _size -= entry->packet->length; 1458832SAli.Saidi@ARM.com _size -= entry->slack; 1468832SAli.Saidi@ARM.com entry->packet = NULL; 1471298SN/A fifo.pop_front(); 1481298SN/A } 1491298SN/A 1501298SN/A void clear() 1512SN/A { 1522SN/A for (iterator i = begin(); i != end(); ++i) 1532SN/A i->clear(); 1542SN/A fifo.clear(); 1552SN/A _size = 0; 1562SN/A _reserved = 0; 1572SN/A } 1582SN/A 1592SN/A void remove(iterator i) 1602SN/A { 1612SN/A if (i != fifo.begin()) { 1625543SN/A iterator prev = i; 1635543SN/A --prev; 1642SN/A assert(prev != fifo.end()); 1652SN/A prev->slack += i->packet->length; 1665543SN/A prev->slack += i->slack; 1675543SN/A } else { 1682SN/A _size -= i->packet->length; 169548SN/A _size -= i->slack; 170548SN/A } 171548SN/A 1722SN/A i->clear(); 1732SN/A fifo.erase(i); 174695SN/A } 1758436SBrad.Beckmann@amd.com 1761400SN/A bool copyout(void *dest, unsigned offset, unsigned len); 1773262SN/A 1783262SN/A int countPacketsBefore(const_iterator i) const 1798436SBrad.Beckmann@amd.com { 1803262SN/A if (i == fifo.end()) 1815999SN/A return 0; 1825999SN/A return i->number - fifo.begin()->number; 1835999SN/A } 1842SN/A 1852SN/A int countPacketsAfter(const_iterator i) const 1863349SN/A { 1873187SN/A auto end = fifo.end(); 1883349SN/A if (i == end) 1893262SN/A return 0; 1903187SN/A return (--end)->number - i->number; 1912SN/A } 1922SN/A 1932SN/A void check() const 1942SN/A { 1951400SN/A unsigned total = 0; 1962SN/A for (auto i = begin(); i != end(); ++i) 1972SN/A total += i->packet->length + i->slack; 1982SN/A 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