Merge ktlim@zizzer:/bk/m5
[gem5.git] / dev / pktfifo.hh
index 0b2e95e2ab32a1afd268e2ed13193f5de55cbc23..e63fd291fa1b52bb635e9b7cdee372d90f8449c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 class Checkpoint;
 class PacketFifo
 {
+  public:
+    typedef std::list<PacketPtr> fifo_list;
+    typedef fifo_list::iterator iterator;
+
   protected:
     std::list<PacketPtr> fifo;
     int _maxsize;
@@ -46,15 +50,16 @@ class PacketFifo
     int _reserved;
 
   public:
-    explicit PacketFifo(int max) : _maxsize(max), _size(0) {}
+    explicit PacketFifo(int max) : _maxsize(max), _size(0), _reserved(0) {}
     virtual ~PacketFifo() {}
 
-    int maxsize() const { return _maxsize; }
     int packets() const { return fifo.size(); }
-    int size() const { return _size + _reserved; }
-    int avail() const { return maxsize() - size(); }
-    bool empty() const { return size() == 0; }
-    bool full() const { return size() >= maxsize(); }
+    int maxsize() const { return _maxsize; }
+    int size() const { return _size; }
+    int reserved() const { return _reserved; }
+    int avail() const { return _maxsize - _size - _reserved; }
+    bool empty() const { return size() <= 0; }
+    bool full() const { return avail() <= 0; }
 
     int reserve(int len = 0)
     {
@@ -63,9 +68,16 @@ class PacketFifo
         return _reserved;
     }
 
+    iterator begin() { return fifo.begin(); }
+    iterator end() { return fifo.end(); }
+
+    PacketPtr front() { return fifo.front(); }
+
     bool push(PacketPtr ptr)
     {
+        assert(ptr->length);
         assert(_reserved <= ptr->length);
+        assert(ptr->slack == 0);
         if (avail() < ptr->length - _reserved)
             return false;
 
@@ -75,22 +87,44 @@ class PacketFifo
         return true;
     }
 
-    PacketPtr front() { return fifo.front(); }
-
     void pop()
     {
         if (empty())
             return;
 
-        _size -= fifo.front()->length;
-        fifo.front() = NULL;
+        PacketPtr &packet = fifo.front();
+        _size -= packet->length;
+        _size -= packet->slack;
+        packet->slack = 0;
+        packet = NULL;
         fifo.pop_front();
     }
 
     void clear()
     {
+        for (iterator i = begin(); i != end(); ++i)
+            (*i)->slack = 0;
         fifo.clear();
         _size = 0;
+        _reserved = 0;
+    }
+
+    void remove(iterator i)
+    {
+        PacketPtr &packet = *i;
+        if (i != fifo.begin()) {
+            iterator prev = i;
+            --prev;
+            assert(prev != fifo.end());
+            (*prev)->slack += packet->length;
+        } else {
+            _size -= packet->length;
+            _size -= packet->slack;
+        }
+
+        packet->slack = 0;
+        packet = NULL;
+        fifo.erase(i);
     }
 
 /**