diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/main.cc | 42 | ||||
-rw-r--r-- | src/sim/pseudo_inst.cc | 6 | ||||
-rw-r--r-- | src/sim/serialize.cc | 117 | ||||
-rw-r--r-- | src/sim/serialize.hh | 7 | ||||
-rw-r--r-- | src/sim/sim_events.cc | 8 | ||||
-rw-r--r-- | src/sim/sim_events.hh | 21 | ||||
-rw-r--r-- | src/sim/sim_object.cc | 64 | ||||
-rw-r--r-- | src/sim/sim_object.hh | 29 |
8 files changed, 178 insertions, 116 deletions
diff --git a/src/sim/main.cc b/src/sim/main.cc index bf844da7f..3eb7fa95d 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -62,6 +62,7 @@ #include "sim/async.hh" #include "sim/builder.hh" #include "sim/host.hh" +#include "sim/serialize.hh" #include "sim/sim_events.hh" #include "sim/sim_exit.hh" #include "sim/sim_object.hh" @@ -521,6 +522,37 @@ simulate(Tick num_cycles = -1) // not reached... only exit is return on SimLoopExitEvent } +Event * +createCountedQuiesce() +{ + return new CountedQuiesceEvent(); +} + +void +cleanupCountedQuiesce(Event *counted_quiesce) +{ + CountedQuiesceEvent *event = + dynamic_cast<CountedQuiesceEvent *>(counted_quiesce); + if (event == NULL) { + fatal("Called cleanupCountedQuiesce() on an event that was not " + "a CountedQuiesceEvent."); + } + assert(event->getCount() == 0); + delete event; +} + +void +serializeAll() +{ + Serializable::serializeAll(); +} + +void +unserializeAll() +{ + Serializable::unserializeAll(); +} + /** * Queue of C++ callbacks to invoke on simulator exit. */ @@ -535,6 +567,16 @@ registerExitCallback(Callback *callback) exitCallbacks.add(callback); } +BaseCPU * +convertToBaseCPUPtr(SimObject *obj) +{ + BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj); + + if (ptr == NULL) + warn("Casting to BaseCPU pointer failed"); + return ptr; +} + /** * Do C++ simulator exit processing. Exported to SWIG to be invoked * when simulator terminates via Python's atexit mechanism. diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index ae52cdd41..b2854e491 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -209,12 +209,6 @@ namespace AlphaPseudo { if (!doCheckpointInsts) return; - - - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; - - Checkpoint::setup(when, repeat); } uint64_t diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 0e3139116..7450d7b7e 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -244,56 +244,41 @@ Serializable::serializeAll() globals.serialize(outstream); SimObject::serializeAll(outstream); - - assert(Serializable::ckptPrevCount + 1 == Serializable::ckptCount); - Serializable::ckptPrevCount++; - if (ckptMaxCount && ++ckptCount >= ckptMaxCount) - exitSimLoop(curTick + 1, "Maximum number of checkpoints dropped"); - } - void -Serializable::unserializeGlobals(Checkpoint *cp) -{ - globals.unserialize(cp); -} - - -class SerializeEvent : public Event +Serializable::unserializeAll() { - protected: - Tick repeat; - - public: - SerializeEvent(Tick _when, Tick _repeat); - virtual void process(); - virtual void serialize(std::ostream &os) - { - panic("Cannot serialize the SerializeEvent"); - } + string dir = Checkpoint::dir(); + string cpt_file = dir + Checkpoint::baseFilename; + string section = ""; -}; + DPRINTFR(Config, "Loading checkpoint dir '%s'\n", + dir); + Checkpoint *cp = new Checkpoint(dir, section); + unserializeGlobals(cp); -SerializeEvent::SerializeEvent(Tick _when, Tick _repeat) - : Event(&mainEventQueue, Serialize_Pri), repeat(_repeat) -{ - setFlags(AutoDelete); - schedule(_when); + SimObject::unserializeAll(cp); } void -SerializeEvent::process() +Serializable::unserializeGlobals(Checkpoint *cp) { - Serializable::serializeAll(); - if (repeat) - schedule(curTick + repeat); + globals.unserialize(cp); } const char *Checkpoint::baseFilename = "m5.cpt"; static string checkpointDirBase; +void +setCheckpointDir(const std::string &name) +{ + checkpointDirBase = name; + if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') + checkpointDirBase += "/"; +} + string Checkpoint::dir() { @@ -304,75 +289,11 @@ Checkpoint::dir() } void -Checkpoint::setup(Tick when, Tick period) -{ - new SerializeEvent(when, period); -} - -class SerializeParamContext : public ParamContext -{ - private: - SerializeEvent *event; - - public: - SerializeParamContext(const string §ion); - ~SerializeParamContext(); - void checkParams(); -}; - -SerializeParamContext serialParams("serialize"); - -Param<string> serialize_dir(&serialParams, "dir", - "dir to stick checkpoint in " - "(sprintf format with cycle #)"); - -Param<Counter> serialize_cycle(&serialParams, - "cycle", - "cycle to serialize", - 0); - -Param<Counter> serialize_period(&serialParams, - "period", - "period to repeat serializations", - 0); - -Param<int> serialize_count(&serialParams, "count", - "maximum number of checkpoints to drop"); - -SerializeParamContext::SerializeParamContext(const string §ion) - : ParamContext(section), event(NULL) -{ } - -SerializeParamContext::~SerializeParamContext() -{ -} - -void -SerializeParamContext::checkParams() -{ - checkpointDirBase = simout.resolve(serialize_dir); - - // guarantee that directory ends with a '/' - if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') - checkpointDirBase += "/"; - - if (serialize_cycle > 0) - Checkpoint::setup(serialize_cycle, serialize_period); - - Serializable::ckptMaxCount = serialize_count; -} - -void debug_serialize() { Serializable::serializeAll(); } -void -debug_serialize(Tick when) -{ - new SerializeEvent(when, 0); -} //////////////////////////////////////////////////////////////////////// // diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 64ed6142f..a80dc99e4 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -127,6 +127,7 @@ class Serializable static int ckptMaxCount; static int ckptPrevCount; static void serializeAll(); + static void unserializeAll(); static void unserializeGlobals(Checkpoint *cp); }; @@ -204,6 +205,9 @@ class SerializableClass SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ OBJ_CLASS::createForUnserialize); +void +setCheckpointName(const std::string &name); + class Checkpoint { private: @@ -237,9 +241,6 @@ class Checkpoint // Filename for base checkpoint file within directory. static const char *baseFilename; - - // Set up a checkpoint creation event or series of events. - static void setup(Tick when, Tick period = 0); }; #endif // __SERIALIZE_HH__ diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc index b7901832d..97f7ae03c 100644 --- a/src/sim/sim_events.cc +++ b/src/sim/sim_events.cc @@ -78,6 +78,14 @@ exitSimLoop(const std::string &message, int exit_code) exitSimLoop(curTick, message, exit_code); } +void +CountedQuiesceEvent::process() +{ + if (--count == 0) { + exitSimLoop("Finished quiesce"); + } +} + // // constructor: automatically schedules at specified time // diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh index 4f305ad38..50368f258 100644 --- a/src/sim/sim_events.hh +++ b/src/sim/sim_events.hh @@ -44,6 +44,11 @@ class SimLoopExitEvent : public Event int code; public: + // Default constructor. Only really used for derived classes. + SimLoopExitEvent() + : Event(&mainEventQueue, Sim_Exit_Pri) + { } + SimLoopExitEvent(Tick _when, const std::string &_cause, int c = 0) : Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause), code(c) @@ -62,6 +67,22 @@ class SimLoopExitEvent : public Event virtual const char *description(); }; +class CountedQuiesceEvent : public SimLoopExitEvent +{ + private: + // Count down to quiescing + int count; + public: + CountedQuiesceEvent() + : count(0) + { } + void process(); + + void setCount(int _count) { count = _count; } + + int getCount() { return count; } +}; + // // Event class to terminate simulation after 'n' related events have // occurred using a shared counter: used to terminate when *all* diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index a35c7a88d..551555b25 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -73,6 +73,7 @@ SimObject::SimObject(Params *p) doRecordEvent = !Stats::event_ignore.match(name()); simObjectList.push_back(this); + state = Atomic; } // @@ -88,6 +89,7 @@ SimObject::SimObject(const string &_name) doRecordEvent = !Stats::event_ignore.match(name()); simObjectList.push_back(this); + state = Atomic; } void @@ -219,6 +221,24 @@ SimObject::serializeAll(ostream &os) } } +void +SimObject::unserializeAll(Checkpoint *cp) +{ + SimObjectList::reverse_iterator ri = simObjectList.rbegin(); + SimObjectList::reverse_iterator rend = simObjectList.rend(); + + for (; ri != rend; ++ri) { + SimObject *obj = *ri; + DPRINTFR(Config, "Unserializing '%s'\n", + obj->name()); + if(cp->sectionExists(obj->name())) + obj->unserialize(cp, obj->name()); + else + warn("Not unserializing '%s': no section found in checkpoint.\n", + obj->name()); + } +} + #ifdef DEBUG // // static function: flag which objects should have the debugger break @@ -250,10 +270,50 @@ SimObject::recordEvent(const std::string &stat) Stats::recordEvent(stat); } +bool +SimObject::quiesce(Event *quiesce_event) +{ + if (state != QuiescedAtomic && state != Atomic) { + panic("Must implement your own quiesce function if it is to be used " + "in timing mode!"); + } + state = QuiescedAtomic; + return false; +} + +void +SimObject::resume() +{ + if (state == QuiescedAtomic) { + state = Atomic; + } else if (state == QuiescedTiming) { + state = Timing; + } +} + +void +SimObject::setMemoryMode(State new_mode) +{ + assert(new_mode == Timing || new_mode == Atomic); + if (state == QuiescedAtomic && new_mode == Timing) { + state = QuiescedTiming; + } else if (state == QuiescedTiming && new_mode == Atomic) { + state = QuiescedAtomic; + } else { + state = new_mode; + } +} + +void +SimObject::switchOut() +{ + panic("Unimplemented!"); +} + void -SimObject::drain(Serializer *serializer) +SimObject::takeOverFrom(BaseCPU *cpu) { - serializer->signalDrained(); + panic("Unimplemented!"); } DEFINE_SIM_OBJECT_CLASS_NAME("SimObject", SimObject) diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 84e9376a0..e0b21782f 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -44,7 +44,8 @@ #include "sim/serialize.hh" #include "sim/startup.hh" -class Serializer; +class BaseCPU; +class Event; /* * Abstract superclass for simulation objects. Represents things that @@ -58,15 +59,26 @@ class SimObject : public Serializable, protected StartupCallback std::string name; }; + enum State { + Atomic, + Timing, + Quiescing, + QuiescedAtomic, + QuiescedTiming + }; + protected: Params *_params; + State state; + + void changeState(State new_state) { state = new_state; } public: const Params *params() const { return _params; } - private: - friend class Serializer; + State getState() { return state; } + private: typedef std::vector<SimObject *> SimObjectList; // list of all instantiated simulation objects @@ -100,13 +112,16 @@ class SimObject : public Serializable, protected StartupCallback // static: call nameOut() & serialize() on all SimObjects static void serializeAll(std::ostream &); + static void unserializeAll(Checkpoint *cp); // Methods to drain objects in order to take checkpoints // Or switch from timing -> atomic memory model - virtual void drain(Serializer *serializer); - virtual void resume() { return;} ; - virtual void serializationComplete() - { assert(0 && "Unimplemented"); }; + // Quiesce returns true if the SimObject cannot quiesce immediately. + virtual bool quiesce(Event *quiesce_event); + virtual void resume(); + virtual void setMemoryMode(State new_mode); + virtual void switchOut(); + virtual void takeOverFrom(BaseCPU *cpu); #ifdef DEBUG public: |