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