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 §ion);
};
@@ -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 §ion)
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 §ion);
};
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev