summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dev/etherpkt.cc2
-rw-r--r--dev/etherpkt.hh24
-rw-r--r--dev/pktfifo.hh38
3 files changed, 56 insertions, 8 deletions
diff --git a/dev/etherpkt.cc b/dev/etherpkt.cc
index 5dee7dc0d..44dbd7c18 100644
--- a/dev/etherpkt.cc
+++ b/dev/etherpkt.cc
@@ -38,6 +38,7 @@ void
PacketData::serialize(const string &base, ostream &os)
{
paramOut(os, base + ".length", length);
+ paramOut(os, base + ".slack", slack);
arrayParamOut(os, base + ".data", data, length);
}
@@ -46,6 +47,7 @@ PacketData::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);
}
diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh
index 82d22bfad..cb9022d72 100644
--- a/dev/etherpkt.hh
+++ b/dev/etherpkt.hh
@@ -47,14 +47,30 @@ class Checkpoint;
class PacketData : public RefCounted
{
public:
+ /*
+ * Pointer to packet data will be deleted
+ */
uint8_t *data;
+
+ /*
+ * Length of the current packet
+ */
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:
- PacketData() : data(NULL), length(0) { }
- explicit PacketData(size_t size) : data(new uint8_t[size]), length(0) { }
- PacketData(std::auto_ptr<uint8_t> d, int l)
- : data(d.release()), length(l) { }
+ PacketData() : data(NULL), length(0), slack(0) { }
+ explicit PacketData(size_t size)
+ : data(new uint8_t[size]), length(0), slack(0) { }
+ PacketData(std::auto_ptr<uint8_t> d, int l, int s = 0)
+ : data(d.release()), length(l), slack(s) { }
~PacketData() { if (data) delete [] data; }
public:
diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh
index a8b626618..61e4ead1b 100644
--- a/dev/pktfifo.hh
+++ b/dev/pktfifo.hh
@@ -39,6 +39,10 @@
class Checkpoint;
class PacketFifo
{
+ public:
+ typedef std::list<PacketPtr> fifo_list;
+ typedef fifo_list::iterator iterator;
+
protected:
std::list<PacketPtr> fifo;
int _maxsize;
@@ -64,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;
@@ -76,25 +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()) {
+ --i;
+ (*i)->slack += packet->length;
+ } else {
+ _size -= packet->length;
+ _size -= packet->slack;
+ }
+
+ packet->slack = 0;
+ packet = NULL;
+ fifo.erase(i);
+ }
+
/**
* Serialization stuff
*/