changeset 3ab1d7ed6545 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=3ab1d7ed6545
description:
        sim: Fix broken event unserialization

        Events expected to be unserialized using an event-specific
        unserializeEvent call. This call was never actually used, which meant
        the events relying on it never got unserialized (or scheduled after
        unserialization).

        Instead of relying on a custom call, we now use the normal
        serialization code again. In order to schedule the event correctly,
        the parrent object is expected to use the
        EventQueue::checkpointReschedule() call. This happens automatically
        for events that are serialized using the AutoSerialize mechanism.

diffstat:

 src/dev/etherlink.cc  |   8 +++-----
 src/sim/eventq.cc     |  39 +++++++++++++++++++++++----------------
 src/sim/eventq.hh     |  19 +++++++++++++------
 src/sim/serialize.hh  |   9 +++++++++
 src/sim/sim_events.cc |  10 ----------
 src/sim/sim_events.hh |   2 --
 6 files changed, 48 insertions(+), 39 deletions(-)

diffs (191 lines):

diff -r a6ca6831e775 -r 3ab1d7ed6545 src/dev/etherlink.cc
--- a/src/dev/etherlink.cc      Tue Jul 07 09:51:03 2015 +0100
+++ b/src/dev/etherlink.cc      Tue Jul 07 09:51:04 2015 +0100
@@ -142,9 +142,7 @@
     void process();
 
     void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
-    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE {}
-    void unserializeEvent(CheckpointIn &cp,
-                          EventQueue *eventq) M5_ATTR_OVERRIDE;
+    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
     static Serializable *createForUnserialize(CheckpointIn &cp,
                                               const string &section);
 };
@@ -260,9 +258,9 @@
 
 
 void
-LinkDelayEvent::unserializeEvent(CheckpointIn &cp, EventQueue *eventq)
+LinkDelayEvent::unserialize(CheckpointIn &cp)
 {
-    Event::unserializeEvent(cp, eventq);
+    Event::unserialize(cp);
 
     EtherLink *parent;
     bool number;
diff -r a6ca6831e775 -r 3ab1d7ed6545 src/sim/eventq.cc
--- a/src/sim/eventq.cc Tue Jul 07 09:51:03 2015 +0100
+++ b/src/sim/eventq.cc Tue Jul 07 09:51:04 2015 +0100
@@ -41,7 +41,7 @@
 #include "base/misc.hh"
 #include "base/trace.hh"
 #include "cpu/smt.hh"
-#include "debug/Config.hh"
+#include "debug/Checkpoint.hh"
 #include "sim/core.hh"
 #include "sim/eventq_impl.hh"
 
@@ -253,18 +253,12 @@
 void
 Event::unserialize(CheckpointIn &cp)
 {
-}
-
-void
-Event::unserializeEvent(CheckpointIn &cp, EventQueue *eventq)
-{
-    if (scheduled())
-        eventq->deschedule(this);
+    assert(!scheduled());
 
     UNSERIALIZE_SCALAR(_when);
     UNSERIALIZE_SCALAR(_priority);
 
-    short _flags;
+    FlagsType _flags;
     UNSERIALIZE_SCALAR(_flags);
 
     // Old checkpoints had no concept of the Initialized flag
@@ -280,12 +274,11 @@
     // need to see if original event was in a scheduled, unsquashed
     // state, but don't want to restore those flags in the current
     // object itself (since they aren't immediately true)
-    bool wasScheduled = flags.isSet(Scheduled) && !flags.isSet(Squashed);
-    flags.clear(Squashed | Scheduled);
-
-    if (wasScheduled) {
-        DPRINTF(Config, "rescheduling at %d\n", _when);
-        eventq->schedule(this, _when);
+    if (flags.isSet(Scheduled) && !flags.isSet(Squashed)) {
+        flags.clear(Squashed | Scheduled);
+    } else {
+        DPRINTF(Checkpoint, "Event '%s' need to be scheduled @%d\n",
+                name(), _when);
     }
 }
 
@@ -329,11 +322,25 @@
         paramIn(cp, csprintf("event%d", i), eventName);
 
         // create the event based on its pointer value
-        Serializable::create(cp, eventName);
+        Serializable *obj(Serializable::create(cp, eventName));
+        Event *event(dynamic_cast<Event *>(obj));
+        fatal_if(!event,
+                 "Event queue unserialized something that wasn't an event.\n");
+
+        checkpointReschedule(event);
     }
 }
 
 void
+EventQueue::checkpointReschedule(Event *event)
+{
+    // It's safe to call insert() directly here since this method
+    // should only be called when restoring from a checkpoint (which
+    // happens before thread creation).
+    if (event->flags.isSet(Event::Scheduled))
+        insert(event);
+}
+void
 EventQueue::dump() const
 {
     cprintf("============================================================\n");
diff -r a6ca6831e775 -r 3ab1d7ed6545 src/sim/eventq.hh
--- a/src/sim/eventq.hh Tue Jul 07 09:51:03 2015 +0100
+++ b/src/sim/eventq.hh Tue Jul 07 09:51:04 2015 +0100
@@ -352,12 +352,6 @@
 #ifndef SWIG
     void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
     void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
-
-    //! This function is required to support restoring from checkpoints
-    //! when running with multiple queues. Since we still have not thrashed
-    //! out all the details on checkpointing, this function is most likely
-    //! to be revisited in future.
-    virtual void unserializeEvent(CheckpointIn &cp, EventQueue *eventq);
 #endif
 };
 
@@ -650,6 +644,19 @@
     void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
 #endif
 
+    /**
+     * Reschedule an event after a checkpoint.
+     *
+     * Since events don't know which event queue they belong to,
+     * parent objects need to reschedule events themselves. This
+     * method conditionally schedules an event that has the Scheduled
+     * flag set. It should be called by parent objects after
+     * unserializing an object.
+     *
+     * @warn Only use this method after unserializing an Event.
+     */
+    void checkpointReschedule(Event *event);
+
     virtual ~EventQueue() { }
 };
 
diff -r a6ca6831e775 -r 3ab1d7ed6545 src/sim/serialize.hh
--- a/src/sim/serialize.hh      Tue Jul 07 09:51:03 2015 +0100
+++ b/src/sim/serialize.hh      Tue Jul 07 09:51:04 2015 +0100
@@ -178,6 +178,15 @@
 #define UNSERIALIZE_CONTAINER(member)           \
         arrayParamIn(cp, #member, member)
 
+#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);
+
+#define UNSERIALIZE_EVENT(event)                        \
+    do {                                                \
+        event.unserializeSection(cp, #event);           \
+        eventQueue()->checkpointReschedule(&event);     \
+    } while(0)
+
+
 #define SERIALIZE_OBJPTR(objptr)        paramOut(cp, #objptr, (objptr)->name())
 
 #define UNSERIALIZE_OBJPTR(objptr)                      \
diff -r a6ca6831e775 -r 3ab1d7ed6545 src/sim/sim_events.cc
--- a/src/sim/sim_events.cc     Tue Jul 07 09:51:03 2015 +0100
+++ b/src/sim/sim_events.cc     Tue Jul 07 09:51:04 2015 +0100
@@ -137,16 +137,6 @@
     UNSERIALIZE_SCALAR(repeat);
 }
 
-void
-LocalSimLoopExitEvent::unserializeEvent(CheckpointIn &cp, EventQueue *eventq)
-{
-    Event::unserializeEvent(cp, eventq);
-
-    UNSERIALIZE_SCALAR(cause);
-    UNSERIALIZE_SCALAR(code);
-    UNSERIALIZE_SCALAR(repeat);
-}
-
 Serializable *
 LocalSimLoopExitEvent::createForUnserialize(CheckpointIn &cp,
                                             const string &section)
diff -r a6ca6831e775 -r 3ab1d7ed6545 src/sim/sim_events.hh
--- a/src/sim/sim_events.hh     Tue Jul 07 09:51:03 2015 +0100
+++ b/src/sim/sim_events.hh     Tue Jul 07 09:51:04 2015 +0100
@@ -95,8 +95,6 @@
 
     void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
     void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
-    void unserializeEvent(CheckpointIn &cp,
-                          EventQueue *eventq) M5_ATTR_OVERRIDE;
     static Serializable *createForUnserialize(CheckpointIn &cp,
                                               const std::string &section);
 };
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to