/*
+ * Copyright (c) 2013 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * Copyright (c) 2013 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "base/callback.hh"
#include "base/hostinfo.hh"
-#include "sim/eventq.hh"
-#include "sim/param.hh"
+#include "sim/eventq_impl.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
-#include "sim/startup.hh"
#include "sim/stats.hh"
using namespace std;
+GlobalSimLoopExitEvent::GlobalSimLoopExitEvent(Tick when,
+ const std::string &_cause,
+ int c, Tick r, bool serialize)
+ : GlobalEvent(when, Sim_Exit_Pri,
+ IsExitEvent | (serialize ? AutoSerialize : 0)),
+ cause(_cause), code(c), repeat(r)
+{
+}
+
+const char *
+GlobalSimLoopExitEvent::description() const
+{
+ return "global simulation loop exit";
+}
+
//
// handle termination event
//
void
-SimExitEvent::process()
+GlobalSimLoopExitEvent::process()
{
- // This event does not autodelete because exitNow may be called,
- // and the function will never be allowed to finish.
- if (theQueue() == &mainEventQueue) {
- string _cause = cause;
- int _code = code;
- delete this;
- exitNow(_cause, _code);
- } else {
- new SimExitEvent(cause, code);
- delete this;
+ if (repeat) {
+ schedule(curTick() + repeat);
}
}
-
-const char *
-SimExitEvent::description()
+void
+exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat,
+ bool serialize)
{
- return "simulation termination";
+ new GlobalSimLoopExitEvent(when + simQuantum, message, exit_code, repeat,
+ serialize);
}
-//
-// constructor: automatically schedules at specified time
-//
-CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause,
- Tick _when, int &_downCounter)
- : Event(q, Sim_Exit_Pri),
- cause(_cause),
- downCounter(_downCounter)
+LocalSimLoopExitEvent::LocalSimLoopExitEvent()
+ : Event(Sim_Exit_Pri, IsExitEvent | AutoSerialize),
+ cause(""), code(0), repeat(0)
{
- // catch stupid mistakes
- assert(downCounter > 0);
-
- schedule(_when);
}
+LocalSimLoopExitEvent::LocalSimLoopExitEvent(const std::string &_cause, int c,
+ Tick r, bool serialize)
+ : Event(Sim_Exit_Pri, IsExitEvent | (serialize ? AutoSerialize : 0)),
+ cause(_cause), code(c), repeat(r)
+{
+}
//
// handle termination event
//
void
-CountedExitEvent::process()
+LocalSimLoopExitEvent::process()
{
- if (--downCounter == 0) {
- new SimExitEvent(cause, 0);
- }
+ exitSimLoop(cause, 0);
}
const char *
-CountedExitEvent::description()
+LocalSimLoopExitEvent::description() const
{
- return "counted exit";
+ return "simulation loop exit";
}
-#ifdef CHECK_SWAP_CYCLES
-new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
-#endif
+void
+LocalSimLoopExitEvent::serialize(ostream &os)
+{
+ paramOut(os, "type", string("SimLoopExitEvent"));
+ Event::serialize(os);
+
+ SERIALIZE_SCALAR(cause);
+ SERIALIZE_SCALAR(code);
+ SERIALIZE_SCALAR(repeat);
+}
void
-CheckSwapEvent::process()
+LocalSimLoopExitEvent::unserialize(Checkpoint *cp, const string §ion)
{
- /* Check the amount of free swap space */
- long swap;
+ Event::unserialize(cp, section);
- /* returns free swap in KBytes */
- swap = procInfo("/proc/meminfo", "SwapFree:");
+ UNSERIALIZE_SCALAR(cause);
+ UNSERIALIZE_SCALAR(code);
+ UNSERIALIZE_SCALAR(repeat);
+}
- if (swap < 1000)
- ccprintf(cerr, "\a\a\aWarning! Swap space is low (%d)\n", swap);
+void
+LocalSimLoopExitEvent::unserialize(Checkpoint *cp, const string §ion,
+ EventQueue *eventq)
+{
+ Event::unserialize(cp, section, eventq);
- if (swap < 100) {
- cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n";
- new SimExitEvent("Lack of swap space");
- }
+ UNSERIALIZE_SCALAR(cause);
+ UNSERIALIZE_SCALAR(code);
+ UNSERIALIZE_SCALAR(repeat);
+}
- schedule(curTick + interval);
+Serializable *
+LocalSimLoopExitEvent::createForUnserialize(Checkpoint *cp,
+ const string §ion)
+{
+ return new LocalSimLoopExitEvent();
}
-const char *
-CheckSwapEvent::description()
+REGISTER_SERIALIZEABLE("LocalSimLoopExitEvent", LocalSimLoopExitEvent)
+
+//
+// constructor: automatically schedules at specified time
+//
+CountedExitEvent::CountedExitEvent(const std::string &_cause, int &counter)
+ : Event(Sim_Exit_Pri), cause(_cause), downCounter(counter)
{
- return "check swap";
+ // catch stupid mistakes
+ assert(downCounter > 0);
}
+
//
-// handle progress event: print message and reschedule
+// handle termination event
//
void
-ProgressEvent::process()
+CountedExitEvent::process()
{
- DPRINTFN("ProgressEvent\n");
- // reschedule for next interval
- schedule(curTick + interval);
+ if (--downCounter == 0) {
+ exitSimLoop(cause, 0);
+ }
}
const char *
-ProgressEvent::description()
+CountedExitEvent::description() const
{
- return "progress message";
+ return "counted exit";
}