PacketFifo: Get slack out of the EthPacketData structure. This allows
authorNathan Binkert <nate@binkert.org>
Wed, 18 Jun 2008 04:34:27 +0000 (21:34 -0700)
committerNathan Binkert <nate@binkert.org>
Wed, 18 Jun 2008 04:34:27 +0000 (21:34 -0700)
a packet to exist in multiple FIFOs if desired.

src/dev/etherpkt.cc
src/dev/etherpkt.hh
src/dev/pktfifo.cc
src/dev/pktfifo.hh
src/dev/sinic.cc

index 5c552b4bd5c9d392341ce7163dcfd53a27cd39ea..2c8343eb05ba242fb42043aedd3df023d117d2b0 100644 (file)
@@ -40,7 +40,6 @@ void
 EthPacketData::serialize(const string &base, ostream &os)
 {
     paramOut(os, base + ".length", length);
-    paramOut(os, base + ".slack", slack);
     arrayParamOut(os, base + ".data", data, length);
 }
 
@@ -49,7 +48,6 @@ EthPacketData::unserialize(const string &base, Checkpoint *cp,
                         const string &section)
 {
     paramIn(cp, section, base + ".length", length);
-    paramIn(cp, section, base + ".slack", slack);
     if (length)
         arrayParamIn(cp, section, base + ".data", data, length);
 }
index db2e0d6b5b5624ab3049c42f1235c38c54d6e8b4..623895ba8774efa5ed788178f48b5fdc7ec06e8a 100644 (file)
@@ -60,24 +60,17 @@ class EthPacketData : public RefCounted
      */
     int length;
 
-    /*
-     * Extra space taken up by the packet in whatever data structure
-     * it is in.
-     *
-     * NOTE: This can only be use by *one* data structure at a time!
-     */
-    int slack;
-
   public:
-    EthPacketData() : data(NULL), length(0), slack(0)
+    EthPacketData()
+        : data(NULL), length(0)
     { }
 
     explicit EthPacketData(size_t size)
-        : data(new uint8_t[size]), length(0), slack(0)
+        : data(new uint8_t[size]), length(0)
     { }
 
-    EthPacketData(std::auto_ptr<uint8_t> d, int l, int s = 0)
-        : data(d.release()), length(l), slack(s)
+    EthPacketData(std::auto_ptr<uint8_t> d, int l)
+        : data(d.release()), length(l)
     { }
 
     ~EthPacketData() { if (data) delete [] data; }
index 37f7ff680286d656bf46e6c19b702e685c52d8b2..97d6c04afdef1fb7b4ee211dcc4c0f0e1f4dab76 100644 (file)
@@ -40,29 +40,50 @@ PacketFifo::copyout(void *dest, int offset, int len)
     if (offset + len >= size())
         return false;
 
-    list<EthPacketPtr>::iterator p = fifo.begin();
-    list<EthPacketPtr>::iterator end = fifo.end();
+    iterator i = fifo.begin();
+    iterator end = fifo.end();
     while (len > 0) {
-        while (offset >= (*p)->length) {
-            offset -= (*p)->length;
-            ++p;
+        EthPacketPtr &pkt = i->packet;
+        while (offset >= pkt->length) {
+            offset -= pkt->length;
+            ++i;
         }
 
-        if (p == end)
+        if (i == end)
             panic("invalid fifo");
 
-        int size = min((*p)->length - offset, len);
-        memcpy(data, (*p)->data, size);
+        int size = min(pkt->length - offset, len);
+        memcpy(data, pkt->data, size);
         offset = 0;
         len -= size;
         data += size;
-        ++p;
+        ++i;
     }
 
     return true;
 }
 
 
+void
+PacketFifoEntry::serialize(const string &base, ostream &os)
+{
+    packet->serialize(base + ".packet", os);
+    paramOut(os, base + ".slack", slack);
+    paramOut(os, base + ".number", number);
+    paramOut(os, base + ".priv", priv);
+}
+
+void
+PacketFifoEntry::unserialize(const string &base, Checkpoint *cp,
+                             const string &section)
+{
+    packet = new EthPacketData(16384);
+    packet->unserialize(base + ".packet", cp, section);
+    paramIn(cp, section, base + ".slack", slack);
+    paramIn(cp, section, base + ".number", number);
+    paramIn(cp, section, base + ".priv", priv);
+}
+
 void
 PacketFifo::serialize(const string &base, ostream &os)
 {
@@ -72,11 +93,11 @@ PacketFifo::serialize(const string &base, ostream &os)
     paramOut(os, base + ".packets", fifo.size());
 
     int i = 0;
-    list<EthPacketPtr>::iterator p = fifo.begin();
-    list<EthPacketPtr>::iterator end = fifo.end();
-    while (p != end) {
-        (*p)->serialize(csprintf("%s.packet%d", base, i), os);
-        ++p;
+    iterator entry = fifo.begin();
+    iterator end = fifo.end();
+    while (entry != end) {
+        entry->serialize(csprintf("%s.entry%d", base, i), os);
+        ++entry;
         ++i;
     }
 }
@@ -94,8 +115,8 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp,
     fifo.clear();
 
     for (int i = 0; i < fifosize; ++i) {
-        EthPacketPtr p = new EthPacketData(16384);
-        p->unserialize(csprintf("%s.packet%d", base, i), cp, section);
-        fifo.push_back(p);
+        PacketFifoEntry entry;
+        entry.unserialize(csprintf("%s.entry%d", base, i), cp, section);
+        fifo.push_back(entry);
     }
 }
index 45157ba416c15b103df8ccfb6678baacaa714cf9..6ded248beba3952bdaa70d4cd6c18f417c4287f6 100644 (file)
 #include "sim/serialize.hh"
 
 class Checkpoint;
+
+struct PacketFifoEntry
+{
+    EthPacketPtr packet;
+    uint64_t number;
+    int slack;
+    int priv;
+
+    PacketFifoEntry()
+    {
+        clear();
+    }
+
+    PacketFifoEntry(const PacketFifoEntry &s)
+        : packet(s.packet), number(s.number), slack(s.slack), priv(s.priv)
+    {
+    }
+
+    PacketFifoEntry(EthPacketPtr p, uint64_t n)
+        : packet(p), number(n), slack(0), priv(-1)
+    {
+    }
+
+    void clear()
+    {
+        packet = NULL;
+        number = 0;
+        slack = 0;
+        priv = -1;
+    }
+
+    void serialize(const std::string &base, std::ostream &os);
+    void unserialize(const std::string &base, Checkpoint *cp,
+                     const std::string &section);
+};
+
 class PacketFifo
 {
   public:
-    typedef std::list<EthPacketPtr> fifo_list;
+
+    typedef std::list<PacketFifoEntry> fifo_list;
     typedef fifo_list::iterator iterator;
 
   protected:
-    std::list<EthPacketPtr> fifo;
+    std::list<PacketFifoEntry> fifo;
+    uint64_t _counter;
     int _maxsize;
     int _size;
     int _reserved;
 
   public:
-    explicit PacketFifo(int max) : _maxsize(max), _size(0), _reserved(0) {}
+    explicit PacketFifo(int max)
+        : _counter(0), _maxsize(max), _size(0), _reserved(0) {}
     virtual ~PacketFifo() {}
 
     int packets() const { return fifo.size(); }
@@ -73,18 +112,21 @@ class PacketFifo
     iterator begin() { return fifo.begin(); }
     iterator end() { return fifo.end(); }
 
-    EthPacketPtr front() { return fifo.front(); }
+    EthPacketPtr front() { return fifo.begin()->packet; }
 
     bool push(EthPacketPtr ptr)
     {
         assert(ptr->length);
         assert(_reserved <= ptr->length);
-        assert(ptr->slack == 0);
         if (avail() < ptr->length - _reserved)
             return false;
 
         _size += ptr->length;
-        fifo.push_back(ptr);
+
+        PacketFifoEntry entry;
+        entry.packet = ptr;
+        entry.number = _counter++;
+        fifo.push_back(entry);
         _reserved = 0;
         return true;
     }
@@ -94,18 +136,17 @@ class PacketFifo
         if (empty())
             return;
 
-        EthPacketPtr &packet = fifo.front();
-        _size -= packet->length;
-        _size -= packet->slack;
-        packet->slack = 0;
-        packet = NULL;
+        iterator entry = fifo.begin();
+        _size -= entry->packet->length;
+        _size -= entry->slack;
+        entry->packet = NULL;
         fifo.pop_front();
     }
 
     void clear()
     {
         for (iterator i = begin(); i != end(); ++i)
-            (*i)->slack = 0;
+            i->clear();
         fifo.clear();
         _size = 0;
         _reserved = 0;
@@ -113,51 +154,48 @@ class PacketFifo
 
     void remove(iterator i)
     {
-        EthPacketPtr &packet = *i;
         if (i != fifo.begin()) {
             iterator prev = i;
             --prev;
             assert(prev != fifo.end());
-            (*prev)->slack += packet->length;
+            prev->slack += i->packet->length;
+            prev->slack += i->slack;
         } else {
-            _size -= packet->length;
-            _size -= packet->slack;
+            _size -= i->packet->length;
+            _size -= i->slack;
         }
 
-        packet->slack = 0;
-        packet = NULL;
+        i->clear();
         fifo.erase(i);
     }
 
     bool copyout(void *dest, int offset, int len);
 
-    int countPacketsBefore(iterator end)
+    int countPacketsBefore(iterator i)
     {
-        iterator i = fifo.begin();
-        int count = 0;
-
-        while (i != end) {
-            ++count;
-            ++i;
-        }
-
-        return count;
+        if (i == fifo.end())
+            return 0;
+        return i->number - fifo.begin()->number;
     }
 
     int countPacketsAfter(iterator i)
     {
         iterator end = fifo.end();
-        int count = 0;
+        if (i == end)
+            return 0;
+        return (--end)->number - i->number;
+    }
 
-        while (i != end) {
-            ++count;
-            ++i;
-        }
+    void check()
+    {
+        int total = 0;
+        for (iterator i = begin(); i != end(); ++i)
+            total += i->packet->length + i->slack;
 
-        return count;
+        if (total != _size)
+            panic("total (%d) is not == to size (%d)\n", total, _size);
     }
 
-
 /**
  * Serialization stuff
  */
index c63966528c2be60830a672daf4fea6819936ad7e..e875a8bcce8b81b6abbe10150d91210f90851fa8 100644 (file)
@@ -893,12 +893,12 @@ Device::rxKick()
         // Grab a new packet from the fifo.
         vnic->rxPacket = rxFifoPtr++;
         vnic->rxPacketOffset = 0;
-        vnic->rxPacketBytes = (*vnic->rxPacket)->length;
+        vnic->rxPacketBytes = vnic->rxPacket->packet->length;
         assert(vnic->rxPacketBytes);
 
         vnic->rxDoneData = 0;
         /* scope for variables */ {
-            IpPtr ip(*vnic->rxPacket);
+            IpPtr ip(vnic->rxPacket->packet);
             if (ip) {
                 DPRINTF(Ethernet, "ID is %d\n", ip->id());
                 vnic->rxDoneData |= Regs::RxDone_IpPacket;
@@ -941,7 +941,7 @@ Device::rxKick()
                 Regs::get_RxData_Addr(vnic->RxData));
         rxDmaLen = std::min<int>(Regs::get_RxData_Len(vnic->RxData),
                             vnic->rxPacketBytes);
-        rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
+        rxDmaData = vnic->rxPacket->packet->data + vnic->rxPacketOffset;
         rxState = rxCopy;
         if (rxDmaAddr == 1LL) {
             rxState = rxCopyDone;