pktfifo.hh revision 11263
11154SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31154SN/A * All rights reserved. 41154SN/A * 51154SN/A * Redistribution and use in source and binary forms, with or without 61154SN/A * modification, are permitted provided that the following conditions are 71154SN/A * met: redistributions of source code must retain the above copyright 81154SN/A * notice, this list of conditions and the following disclaimer; 91154SN/A * redistributions in binary form must reproduce the above copyright 101154SN/A * notice, this list of conditions and the following disclaimer in the 111154SN/A * documentation and/or other materials provided with the distribution; 121154SN/A * neither the name of the copyright holders nor the names of its 131154SN/A * contributors may be used to endorse or promote products derived from 141154SN/A * this software without specific prior written permission. 151154SN/A * 161154SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171154SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181154SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191154SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201154SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211154SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221154SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231154SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241154SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251154SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261154SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Nathan Binkert 291154SN/A */ 301154SN/A 3111263Sandreas.sandberg@arm.com#ifndef __DEV_NET_PKTFIFO_HH__ 3211263Sandreas.sandberg@arm.com#define __DEV_NET_PKTFIFO_HH__ 331154SN/A 341154SN/A#include <iosfwd> 351154SN/A#include <list> 361154SN/A#include <string> 371154SN/A 3811263Sandreas.sandberg@arm.com#include "base/misc.hh" 3911263Sandreas.sandberg@arm.com#include "dev/net/etherpkt.hh" 401154SN/A#include "sim/serialize.hh" 411154SN/A 421154SN/Aclass Checkpoint; 435483SN/A 445483SN/Astruct PacketFifoEntry 455483SN/A{ 465483SN/A EthPacketPtr packet; 475483SN/A uint64_t number; 486227SN/A unsigned slack; 495483SN/A int priv; 505483SN/A 515483SN/A PacketFifoEntry() 525483SN/A { 535483SN/A clear(); 545483SN/A } 555483SN/A 565483SN/A PacketFifoEntry(const PacketFifoEntry &s) 575483SN/A : packet(s.packet), number(s.number), slack(s.slack), priv(s.priv) 585483SN/A { 595483SN/A } 605483SN/A 615483SN/A PacketFifoEntry(EthPacketPtr p, uint64_t n) 625483SN/A : packet(p), number(n), slack(0), priv(-1) 635483SN/A { 645483SN/A } 655483SN/A 665483SN/A void clear() 675483SN/A { 685483SN/A packet = NULL; 695483SN/A number = 0; 705483SN/A slack = 0; 715483SN/A priv = -1; 725483SN/A } 735483SN/A 7410905SN/A void serialize(const std::string &base, CheckpointOut &cp) const; 7510905SN/A void unserialize(const std::string &base, CheckpointIn &cp); 765483SN/A}; 775483SN/A 781154SN/Aclass PacketFifo 791154SN/A{ 802007SN/A public: 815483SN/A 825483SN/A typedef std::list<PacketFifoEntry> fifo_list; 832007SN/A typedef fifo_list::iterator iterator; 8411006SN/A typedef fifo_list::const_iterator const_iterator; 852007SN/A 861154SN/A protected: 875483SN/A std::list<PacketFifoEntry> fifo; 885483SN/A uint64_t _counter; 896227SN/A unsigned _maxsize; 906227SN/A unsigned _size; 916227SN/A unsigned _reserved; 921154SN/A 931154SN/A public: 945483SN/A explicit PacketFifo(int max) 955483SN/A : _counter(0), _maxsize(max), _size(0), _reserved(0) {} 961154SN/A virtual ~PacketFifo() {} 971154SN/A 986227SN/A unsigned packets() const { return fifo.size(); } 996227SN/A unsigned maxsize() const { return _maxsize; } 1006227SN/A unsigned size() const { return _size; } 1016227SN/A unsigned reserved() const { return _reserved; } 1026227SN/A unsigned avail() const { return _maxsize - _size - _reserved; } 1031214SN/A bool empty() const { return size() <= 0; } 1041214SN/A bool full() const { return avail() <= 0; } 1051205SN/A 1066227SN/A unsigned 1076227SN/A reserve(unsigned len = 0) 1081205SN/A { 1091205SN/A _reserved += len; 1101205SN/A assert(avail() >= 0); 1111205SN/A return _reserved; 1121205SN/A } 1131154SN/A 1142007SN/A iterator begin() { return fifo.begin(); } 1152007SN/A iterator end() { return fifo.end(); } 1162007SN/A 11711006SN/A const_iterator begin() const { return fifo.begin(); } 11811006SN/A const_iterator end() const { return fifo.end(); } 11911006SN/A 1205483SN/A EthPacketPtr front() { return fifo.begin()->packet; } 1212007SN/A 1222566SN/A bool push(EthPacketPtr ptr) 1231154SN/A { 1242007SN/A assert(ptr->length); 1251205SN/A assert(_reserved <= ptr->length); 1261205SN/A if (avail() < ptr->length - _reserved) 1271154SN/A return false; 1281154SN/A 1291154SN/A _size += ptr->length; 1305483SN/A 1315483SN/A PacketFifoEntry entry; 1325483SN/A entry.packet = ptr; 1335483SN/A entry.number = _counter++; 1345483SN/A fifo.push_back(entry); 1351205SN/A _reserved = 0; 1361154SN/A return true; 1371154SN/A } 1381154SN/A 1391154SN/A void pop() 1401154SN/A { 1411154SN/A if (empty()) 1421154SN/A return; 1431154SN/A 1445483SN/A iterator entry = fifo.begin(); 1455483SN/A _size -= entry->packet->length; 1465483SN/A _size -= entry->slack; 1475483SN/A entry->packet = NULL; 1481154SN/A fifo.pop_front(); 1491154SN/A } 1501154SN/A 1511154SN/A void clear() 1521154SN/A { 1532007SN/A for (iterator i = begin(); i != end(); ++i) 1545483SN/A i->clear(); 1551154SN/A fifo.clear(); 1561154SN/A _size = 0; 1571214SN/A _reserved = 0; 1581154SN/A } 1591154SN/A 1602007SN/A void remove(iterator i) 1612007SN/A { 1622007SN/A if (i != fifo.begin()) { 1632010SN/A iterator prev = i; 1642010SN/A --prev; 1652010SN/A assert(prev != fifo.end()); 1665483SN/A prev->slack += i->packet->length; 1675483SN/A prev->slack += i->slack; 1682007SN/A } else { 1695483SN/A _size -= i->packet->length; 1705483SN/A _size -= i->slack; 1712007SN/A } 1722007SN/A 1735483SN/A i->clear(); 1742007SN/A fifo.erase(i); 1752007SN/A } 1762007SN/A 1776227SN/A bool copyout(void *dest, unsigned offset, unsigned len); 1782186SN/A 17911006SN/A int countPacketsBefore(const_iterator i) const 1802186SN/A { 1815483SN/A if (i == fifo.end()) 1825483SN/A return 0; 1835483SN/A return i->number - fifo.begin()->number; 1842186SN/A } 1852186SN/A 18611006SN/A int countPacketsAfter(const_iterator i) const 1872186SN/A { 18811006SN/A auto end = fifo.end(); 1895483SN/A if (i == end) 1905483SN/A return 0; 1915483SN/A return (--end)->number - i->number; 1922186SN/A } 1932186SN/A 19411006SN/A void check() const 1955483SN/A { 1966227SN/A unsigned total = 0; 19711006SN/A for (auto i = begin(); i != end(); ++i) 1985483SN/A total += i->packet->length + i->slack; 1995483SN/A 2005483SN/A if (total != _size) 2015483SN/A panic("total (%d) is not == to size (%d)\n", total, _size); 2025483SN/A } 2032186SN/A 2041154SN/A/** 2051154SN/A * Serialization stuff 2061154SN/A */ 2071154SN/A public: 20810905SN/A void serialize(const std::string &base, CheckpointOut &cp) const; 20910905SN/A void unserialize(const std::string &base, CheckpointIn &cp); 2101154SN/A}; 2111154SN/A 21211263Sandreas.sandberg@arm.com#endif // __DEV_NET_PKTFIFO_HH__ 213