From b9c847563d9c10164e015feef8ef25ce76551843 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 8 Mar 2005 12:47:55 -0500 Subject: [PATCH] Fix serialization of the EtherLink object dev/etherlink.cc: - The EtherLink::Link object is no lonver serializable, so it is now necessary to prepend the object's name (as determined by the parent) to all parameters. - Fix the serialization of the LinkDelayEvent so it actually works - Rename some variables to make serialization simpler dev/etherlink.hh: - Make the EtherLink::Link object *not* derive from serializeable. Instead, the serialize function will take a base name from the parent EtherLink object and prepend that base name to each of its variable names when serializing. This is similar to the PacketData and PacketFifo classes. - Make the EtherLink::Link object keep a pointer to its parent and its link number so the LinkDelayEvent can be properly serialized. - Rename some variables to make serialization simpler. --HG-- extra : convert_revision : e5aa54cd9e07b5e033989809100e1640abfb8bed --- dev/etherlink.cc | 98 ++++++++++++++++++++++++++---------------------- dev/etherlink.hh | 28 +++++++------- 2 files changed, 68 insertions(+), 58 deletions(-) diff --git a/dev/etherlink.cc b/dev/etherlink.cc index 0acc50b0b..94293815d 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -47,32 +47,32 @@ using namespace std; -EtherLink::EtherLink(const string &name, EtherInt *i1, EtherInt *i2, +EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, Tick speed, Tick dly, EtherDump *dump) : SimObject(name) { double rate = ((double)ticksPerSecond * 8.0) / (double)speed; Tick delay = US2Ticks(dly); - link1 = new Link(name + ".link1", rate, delay, dump); - link2 = new Link(name + ".link2", rate, delay, dump); + link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); + link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); - int1 = new Interface(name + ".int1", link1, link2); - int2 = new Interface(name + ".int2", link2, link1); + interface[0] = new Interface(name + ".int0", link[0], link[1]); + interface[1] = new Interface(name + ".int1", link[1], link[0]); - int1->setPeer(i1); - i1->setPeer(int1); - int2->setPeer(i2); - i2->setPeer(int2); + interface[0]->setPeer(peer0); + peer0->setPeer(interface[0]); + interface[1]->setPeer(peer1); + peer1->setPeer(interface[1]); } EtherLink::~EtherLink() { - delete link1; - delete link2; + delete link[0]; + delete link[1]; - delete int1; - delete int2; + delete interface[0]; + delete interface[1]; } EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) @@ -82,26 +82,25 @@ EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) rx->setRxInt(this); } -EtherLink::Link::Link(const string &name, double rate, Tick delay, - EtherDump *d) - : objName(name), txint(NULL), rxint(NULL), ticksPerByte(rate), - linkDelay(delay), dump(d), doneEvent(this) -{} +EtherLink::Link::Link(const string &name, EtherLink *p, int num, + double rate, Tick delay, EtherDump *d) + : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), + ticksPerByte(rate), linkDelay(delay), dump(d), + doneEvent(this) +{ } void EtherLink::serialize(ostream &os) { - nameOut(os, name() + ".link1"); - link1->serialize(os); - nameOut(os, name() + ".link2"); - link2->serialize(os); + link[0]->serialize("link0", os); + link[1]->serialize("link1", os); } void EtherLink::unserialize(Checkpoint *cp, const string §ion) { - link1->unserialize(cp, section + ".link1"); - link2->unserialize(cp, section + ".link2"); + link[0]->unserialize("link0", cp, section); + link[1]->unserialize("link1", cp, section); } void @@ -118,10 +117,9 @@ class LinkDelayEvent : public Event EtherLink::Link *link; PacketPtr packet; - // non-scheduling version for createForUnserialize() - LinkDelayEvent(EtherLink::Link *link); - public: + // non-scheduling version for createForUnserialize() + LinkDelayEvent(); LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); void process(); @@ -132,7 +130,6 @@ class LinkDelayEvent : public Event const string §ion); }; - void EtherLink::Link::txDone() { @@ -173,43 +170,44 @@ EtherLink::Link::transmit(PacketPtr pkt) } void -EtherLink::Link::serialize(ostream &os) +EtherLink::Link::serialize(const string &base, ostream &os) { bool packet_exists = packet; - SERIALIZE_SCALAR(packet_exists); + paramOut(os, base + ".packet_exists", packet_exists); + if (packet_exists) + packet->serialize(base + ".packet", os); bool event_scheduled = doneEvent.scheduled(); - SERIALIZE_SCALAR(event_scheduled); + paramOut(os, base + ".event_scheuled", event_scheduled); if (event_scheduled) { Tick event_time = doneEvent.when(); - SERIALIZE_SCALAR(event_time); + paramOut(os, base + ".event_time", event_time); } - if (packet_exists) - packet->serialize("packet", os); } void -EtherLink::Link::unserialize(Checkpoint *cp, const string §ion) +EtherLink::Link::unserialize(const string &base, Checkpoint *cp, + const string §ion) { bool packet_exists; - UNSERIALIZE_SCALAR(packet_exists); + paramIn(cp, section, base + ".packet_exists", packet_exists); if (packet_exists) { packet = new PacketData(16384); - packet->unserialize("packet", cp, section); + packet->unserialize(base + ".packet", cp, section); } bool event_scheduled; - UNSERIALIZE_SCALAR(event_scheduled); + paramIn(cp, section, base + ".event_scheduled", event_scheduled); if (event_scheduled) { Tick event_time; - UNSERIALIZE_SCALAR(event_time); + paramIn(cp, section, base + ".event_time", event_time); doneEvent.schedule(event_time); } } -LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l) - : Event(&mainEventQueue), link(l) +LinkDelayEvent::LinkDelayEvent() + : Event(&mainEventQueue), link(NULL) { setFlags(AutoSerialize); setFlags(AutoDelete); @@ -234,7 +232,11 @@ LinkDelayEvent::serialize(ostream &os) { paramOut(os, "type", string("LinkDelayEvent")); Event::serialize(os); - SERIALIZE_OBJPTR(link); + + EtherLink *parent = link->parent; + bool number = link->number; + SERIALIZE_OBJPTR(parent); + SERIALIZE_SCALAR(number); packet->serialize("packet", os); } @@ -244,6 +246,14 @@ void LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) { Event::unserialize(cp, section); + + EtherLink *parent; + bool number; + UNSERIALIZE_OBJPTR(parent); + UNSERIALIZE_SCALAR(number); + + link = parent->link[number]; + packet = new PacketData(16384); packet->unserialize("packet", cp, section); } @@ -252,9 +262,7 @@ LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) Serializable * LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) { - EtherLink::Link *link; - UNSERIALIZE_OBJPTR(link); - return new LinkDelayEvent(link); + return new LinkDelayEvent(); } REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) diff --git a/dev/etherlink.hh b/dev/etherlink.hh index d5cd7d7c8..28ab61301 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -40,7 +40,7 @@ #include "sim/sim_object.hh" class EtherDump; - +class Checkpoint; /* * Model for a fixed bandwidth full duplex ethernet link */ @@ -53,10 +53,14 @@ class EtherLink : public SimObject /* * Model for a single uni-directional link */ - class Link : public Serializable { + class Link + { protected: std::string objName; + EtherLink *parent; + int number; + Interface *txint; Interface *rxint; @@ -78,11 +82,11 @@ class EtherLink : public SimObject void txComplete(PacketPtr packet); public: - Link(const std::string &name, double rate, Tick delay, - EtherDump *dump); + Link(const std::string &name, EtherLink *p, int num, + double rate, Tick delay, EtherDump *dump); ~Link() {} - virtual const std::string name() const { return objName; } + const std::string name() const { return objName; } bool busy() const { return (bool)packet; } bool transmit(PacketPtr packet); @@ -90,8 +94,9 @@ class EtherLink : public SimObject void setTxInt(Interface *i) { assert(!txint); txint = i; } void setRxInt(Interface *i) { assert(!rxint); rxint = i; } - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); }; /* @@ -108,14 +113,11 @@ class EtherLink : public SimObject void sendDone() { peer->sendDone(); } }; - Link *link1; - Link *link2; - - EtherInt *int1; - EtherInt *int2; + Link *link[2]; + EtherInt *interface[2]; public: - EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2, + EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1, Tick speed, Tick delay, EtherDump *dump); virtual ~EtherLink();