diff -r 68a540906d61 -r 01c1fa498765 src/sim/sim_events.hh --- a/src/sim/sim_events.hh Mon Jun 08 17:57:02 2015 +0100 +++ b/src/sim/sim_events.hh Mon Jun 08 17:57:38 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); }; diff -r 68a540906d61 -r 01c1fa498765 src/sim/sim_events.cc --- a/src/sim/sim_events.cc Mon Jun 08 17:57:02 2015 +0100 +++ b/src/sim/sim_events.cc Mon Jun 08 17:57:38 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 68a540906d61 -r 01c1fa498765 src/dev/etherlink.cc --- a/src/dev/etherlink.cc Mon Jun 08 17:57:02 2015 +0100 +++ b/src/dev/etherlink.cc Mon Jun 08 17:57:38 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 68a540906d61 -r 01c1fa498765 src/sim/eventq.hh --- a/src/sim/eventq.hh Mon Jun 08 17:57:02 2015 +0100 +++ b/src/sim/eventq.hh Mon Jun 08 17:57:38 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 68a540906d61 -r 01c1fa498765 src/sim/eventq.cc --- a/src/sim/eventq.cc Mon Jun 08 17:57:02 2015 +0100 +++ b/src/sim/eventq.cc Mon Jun 08 17:57:38 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(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 68a540906d61 -r 01c1fa498765 src/sim/serialize.hh --- a/src/sim/serialize.hh Mon Jun 08 17:57:02 2015 +0100 +++ b/src/sim/serialize.hh Mon Jun 08 17:57:38 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) \