summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2015-07-07 09:51:04 +0100
committerAndreas Sandberg <andreas.sandberg@arm.com>2015-07-07 09:51:04 +0100
commit888ec455cba4174863be5ed9148aaf093a061101 (patch)
treeccf37fcf4b72fc5de4dcea4ec730aab7f660e572 /src
parent76cd4393c08b83fa9006ee7bce1fb62457e053c1 (diff)
downloadgem5-888ec455cba4174863be5ed9148aaf093a061101.tar.xz
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 (limited to 'src')
-rw-r--r--src/dev/etherlink.cc8
-rw-r--r--src/sim/eventq.cc39
-rw-r--r--src/sim/eventq.hh19
-rw-r--r--src/sim/serialize.hh9
-rw-r--r--src/sim/sim_events.cc10
-rw-r--r--src/sim/sim_events.hh2
6 files changed, 48 insertions, 39 deletions
diff --git a/src/dev/etherlink.cc b/src/dev/etherlink.cc
index 27179d508..7b24fe9f7 100644
--- a/src/dev/etherlink.cc
+++ b/src/dev/etherlink.cc
@@ -142,9 +142,7 @@ class LinkDelayEvent : public Event
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 @@ LinkDelayEvent::serialize(CheckpointOut &cp) const
void
-LinkDelayEvent::unserializeEvent(CheckpointIn &cp, EventQueue *eventq)
+LinkDelayEvent::unserialize(CheckpointIn &cp)
{
- Event::unserializeEvent(cp, eventq);
+ Event::unserialize(cp);
EtherLink *parent;
bool number;
diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc
index f75ada47c..48664f8e8 100644
--- a/src/sim/eventq.cc
+++ b/src/sim/eventq.cc
@@ -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 @@ Event::serialize(CheckpointOut &cp) const
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 @@ Event::unserializeEvent(CheckpointIn &cp, EventQueue *eventq)
// 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 @@ EventQueue::unserialize(CheckpointIn &cp)
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 --git a/src/sim/eventq.hh b/src/sim/eventq.hh
index b90e5d382..cfb79614f 100644
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -352,12 +352,6 @@ class Event : public EventBase, public Serializable
#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 @@ class EventQueue : public Serializable
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 --git a/src/sim/serialize.hh b/src/sim/serialize.hh
index 644ef4005..a0d4bafe7 100644
--- a/src/sim/serialize.hh
+++ b/src/sim/serialize.hh
@@ -178,6 +178,15 @@ void fromSimObject(T &t, SimObject *s)
#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 --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc
index 719a732ab..94bd06191 100644
--- a/src/sim/sim_events.cc
+++ b/src/sim/sim_events.cc
@@ -137,16 +137,6 @@ LocalSimLoopExitEvent::unserialize(CheckpointIn &cp)
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 --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh
index 8d5d5da7b..7c2393010 100644
--- a/src/sim/sim_events.hh
+++ b/src/sim/sim_events.hh
@@ -95,8 +95,6 @@ class LocalSimLoopExitEvent : public Event
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);
};