pktfifo.hh revision 2566
16657Snate@binkert.org/* 26657Snate@binkert.org * Copyright (c) 2004-2005 The Regents of The University of Michigan 36657Snate@binkert.org * All rights reserved. 46657Snate@binkert.org * 56657Snate@binkert.org * Redistribution and use in source and binary forms, with or without 66657Snate@binkert.org * modification, are permitted provided that the following conditions are 76657Snate@binkert.org * met: redistributions of source code must retain the above copyright 86657Snate@binkert.org * notice, this list of conditions and the following disclaimer; 96657Snate@binkert.org * redistributions in binary form must reproduce the above copyright 106657Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 116657Snate@binkert.org * documentation and/or other materials provided with the distribution; 126657Snate@binkert.org * neither the name of the copyright holders nor the names of its 136657Snate@binkert.org * contributors may be used to endorse or promote products derived from 146657Snate@binkert.org * this software without specific prior written permission. 156657Snate@binkert.org * 166657Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657Snate@binkert.org */ 288453Snate@binkert.org 296657Snate@binkert.org#ifndef __DEV_PKTFIFO_HH__ 306657Snate@binkert.org#define __DEV_PKTFIFO_HH__ 316657Snate@binkert.org 326657Snate@binkert.org#include <iosfwd> 336657Snate@binkert.org#include <list> 346657Snate@binkert.org#include <string> 356657Snate@binkert.org 366999Snate@binkert.org#include "dev/etherpkt.hh" 376999Snate@binkert.org#include "sim/serialize.hh" 386999Snate@binkert.org 396657Snate@binkert.orgclass Checkpoint; 406657Snate@binkert.orgclass PacketFifo 416657Snate@binkert.org{ 426657Snate@binkert.org public: 436657Snate@binkert.org typedef std::list<EthPacketPtr> fifo_list; 446657Snate@binkert.org typedef fifo_list::iterator iterator; 458453Snate@binkert.org 468453Snate@binkert.org protected: 476657Snate@binkert.org std::list<EthPacketPtr> fifo; 486657Snate@binkert.org int _maxsize; 496657Snate@binkert.org int _size; 506657Snate@binkert.org int _reserved; 516657Snate@binkert.org 528453Snate@binkert.org public: 538453Snate@binkert.org explicit PacketFifo(int max) : _maxsize(max), _size(0), _reserved(0) {} 546657Snate@binkert.org virtual ~PacketFifo() {} 556657Snate@binkert.org 566657Snate@binkert.org int packets() const { return fifo.size(); } 576657Snate@binkert.org int maxsize() const { return _maxsize; } 586657Snate@binkert.org int size() const { return _size; } 596999Snate@binkert.org int reserved() const { return _reserved; } 606999Snate@binkert.org int avail() const { return _maxsize - _size - _reserved; } 616999Snate@binkert.org bool empty() const { return size() <= 0; } 626657Snate@binkert.org bool full() const { return avail() <= 0; } 636657Snate@binkert.org 646657Snate@binkert.org int reserve(int len = 0) 656657Snate@binkert.org { 666657Snate@binkert.org _reserved += len; 676657Snate@binkert.org assert(avail() >= 0); 686657Snate@binkert.org return _reserved; 696657Snate@binkert.org } 706657Snate@binkert.org 716657Snate@binkert.org iterator begin() { return fifo.begin(); } 726657Snate@binkert.org iterator end() { return fifo.end(); } 736657Snate@binkert.org 746657Snate@binkert.org EthPacketPtr front() { return fifo.front(); } 756657Snate@binkert.org 766657Snate@binkert.org bool push(EthPacketPtr ptr) 776657Snate@binkert.org { 786657Snate@binkert.org assert(ptr->length); 796657Snate@binkert.org assert(_reserved <= ptr->length); 806657Snate@binkert.org assert(ptr->slack == 0); 816657Snate@binkert.org if (avail() < ptr->length - _reserved) 826794SBrad.Beckmann@amd.com return false; 836794SBrad.Beckmann@amd.com 849302Snilay@cs.wisc.edu _size += ptr->length; 856657Snate@binkert.org fifo.push_back(ptr); 866657Snate@binkert.org _reserved = 0; 876657Snate@binkert.org return true; 886657Snate@binkert.org } 896657Snate@binkert.org 906657Snate@binkert.org void pop() 916657Snate@binkert.org { 926657Snate@binkert.org if (empty()) 936657Snate@binkert.org return; 946657Snate@binkert.org 956657Snate@binkert.org EthPacketPtr &packet = fifo.front(); 966657Snate@binkert.org _size -= packet->length; 976657Snate@binkert.org _size -= packet->slack; 986657Snate@binkert.org packet->slack = 0; 996657Snate@binkert.org packet = NULL; 1006657Snate@binkert.org fifo.pop_front(); 1016657Snate@binkert.org } 1026657Snate@binkert.org 1036657Snate@binkert.org void clear() 1046657Snate@binkert.org { 1056657Snate@binkert.org for (iterator i = begin(); i != end(); ++i) 1066657Snate@binkert.org (*i)->slack = 0; 1076657Snate@binkert.org fifo.clear(); 1086657Snate@binkert.org _size = 0; 1096657Snate@binkert.org _reserved = 0; 1106657Snate@binkert.org } 1116657Snate@binkert.org 1126657Snate@binkert.org void remove(iterator i) 1136657Snate@binkert.org { 1146657Snate@binkert.org EthPacketPtr &packet = *i; 1156657Snate@binkert.org if (i != fifo.begin()) { 1166657Snate@binkert.org iterator prev = i; 1176657Snate@binkert.org --prev; 1186657Snate@binkert.org assert(prev != fifo.end()); 1196657Snate@binkert.org (*prev)->slack += packet->length; 1206657Snate@binkert.org } else { 1216657Snate@binkert.org _size -= packet->length; 1226657Snate@binkert.org _size -= packet->slack; 1236657Snate@binkert.org } 1246657Snate@binkert.org 1256657Snate@binkert.org packet->slack = 0; 1269219Spower.jg@gmail.com packet = NULL; 1278453Snate@binkert.org fifo.erase(i); 1288453Snate@binkert.org } 1296999Snate@binkert.org 1309219Spower.jg@gmail.com bool copyout(void *dest, int offset, int len); 1316657Snate@binkert.org 1329219Spower.jg@gmail.com int countPacketsBefore(iterator end) 1339219Spower.jg@gmail.com { 1349219Spower.jg@gmail.com iterator i = fifo.begin(); 1356657Snate@binkert.org int count = 0; 1366657Snate@binkert.org 1376657Snate@binkert.org while (i != end) { 1386657Snate@binkert.org ++count; 1396657Snate@binkert.org ++i; 1406657Snate@binkert.org } 1416657Snate@binkert.org 1429219Spower.jg@gmail.com return count; 1436657Snate@binkert.org } 1446657Snate@binkert.org 1458453Snate@binkert.org int countPacketsAfter(iterator i) 1468453Snate@binkert.org { 1476657Snate@binkert.org iterator end = fifo.end(); 1486657Snate@binkert.org int count = 0; 1496657Snate@binkert.org 1506657Snate@binkert.org while (i != end) { 1516657Snate@binkert.org ++count; 1526657Snate@binkert.org ++i; 1536999Snate@binkert.org } 1546657Snate@binkert.org 1556657Snate@binkert.org return count; 1566657Snate@binkert.org } 1576657Snate@binkert.org 1586657Snate@binkert.org 1596657Snate@binkert.org/** 1606657Snate@binkert.org * Serialization stuff 1616657Snate@binkert.org */ 1626657Snate@binkert.org public: 1636657Snate@binkert.org void serialize(const std::string &base, std::ostream &os); 1646657Snate@binkert.org void unserialize(const std::string &base, 1656657Snate@binkert.org Checkpoint *cp, const std::string §ion); 1666657Snate@binkert.org}; 1676999Snate@binkert.org 1686657Snate@binkert.org#endif // __DEV_PKTFIFO_HH__ 1696657Snate@binkert.org