summaryrefslogtreecommitdiff
path: root/sim/sim_events.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sim/sim_events.cc')
-rw-r--r--sim/sim_events.cc271
1 files changed, 271 insertions, 0 deletions
diff --git a/sim/sim_events.cc b/sim/sim_events.cc
new file mode 100644
index 000000000..ffabc3006
--- /dev/null
+++ b/sim/sim_events.cc
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "cpu.hh"
+#include "eventq.hh"
+#include "sim_events.hh"
+#include "sim_exit.hh"
+#include "sim_stats.hh"
+
+using namespace std;
+
+//
+// handle termination event
+//
+void
+SimExitEvent::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;
+ }
+}
+
+
+const char *
+SimExitEvent::description()
+{
+ return "simulation termination";
+}
+
+
+//
+// constructor: automatically schedules at specified time
+//
+CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause,
+ Tick _when, int &_downCounter)
+ : Event(q),
+ cause(_cause),
+ downCounter(_downCounter)
+{
+ // catch stupid mistakes
+ assert(downCounter > 0);
+
+ schedule(_when, 1000);
+}
+
+
+//
+// handle termination event
+//
+void
+CountedExitEvent::process()
+{
+ if (--downCounter == 0) {
+ new SimExitEvent(cause, 1);
+ }
+}
+
+
+const char *
+CountedExitEvent::description()
+{
+ return "counted exit";
+}
+
+
+void
+DumpStatsEvent::process()
+{
+ dumpStats();
+}
+
+const char *
+DumpStatsEvent::description()
+{
+ return "stats dump";
+}
+
+
+#ifdef CHECK_SWAP_CYCLES
+new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
+#endif
+
+void
+CheckSwapEvent::process()
+{
+ /* Check the amount of free swap space */
+ long swap;
+
+ /* returns free swap in KBytes */
+ swap = proc_info("/proc/meminfo", "SwapFree:");
+
+ if (swap < 1000)
+ ccprintf(cerr, "\a\a\aWarning! Swap space is low (%d)\n", swap);
+
+ if (swap < 100) {
+ cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n";
+ new SimExitEvent("Lack of swap space");
+ }
+
+ schedule(curTick + interval);
+}
+
+const char *
+CheckSwapEvent::description()
+{
+ return "check swap";
+}
+
+
+class DumpStatsContext : public ParamContext
+{
+ public:
+ DumpStatsContext(const string &_iniSection)
+ : ParamContext(_iniSection) {}
+ void checkParams();
+};
+
+DumpStatsContext dumpStatsParams("stats");
+
+VectorParam<Tick> dump_cycle(&dumpStatsParams, "dump_cycles",
+ "cycles on which to dump stats");
+
+void
+DumpStatsContext::checkParams()
+{
+ if (dump_cycle.isValid()) {
+ vector<Tick> &cycles = dump_cycle;
+
+ vector<Tick>::iterator i = cycles.begin();
+ vector<Tick>::iterator end = cycles.end();
+
+ for (; i < end; ++i)
+ new DumpStatsEvent(*i);
+ }
+}
+
+///////////////////////////////////////////////////
+//
+// Simulation termination parameters
+//
+///////////////////////////////////////////////////
+
+class TermParamContext : public ParamContext
+{
+ public:
+ TermParamContext(const string &_iniSection)
+ : ParamContext(_iniSection) {}
+ void checkParams();
+};
+
+TermParamContext simTerminationParams("max");
+
+Param<Tick> max_cycle(&simTerminationParams, "cycle",
+ "maximum number of cycles to execute");
+
+void
+TermParamContext::checkParams()
+{
+ // if a max cycle count was specified, put a termination event on
+ // the event queue at that point
+ if (max_cycle.isValid())
+ new SimExitEvent(max_cycle, "reached maximum cycle count");
+}
+
+//
+// Progress event: print out cycle every so often so we know we're
+// making forward progress.
+//
+class ProgressEvent : public Event
+{
+ protected:
+ Tick interval;
+
+ public:
+ ProgressEvent(EventQueue *q, Tick interval);
+
+ void process(); // process event
+ virtual const char *description();
+};
+
+//
+// constructor: schedule at specified time
+//
+ProgressEvent::ProgressEvent(EventQueue *q, Tick _interval)
+ : Event(q), interval(_interval)
+{
+ schedule(interval);
+}
+
+//
+// handle progress event: print message and reschedule
+//
+void
+ProgressEvent::process()
+{
+ DPRINTFN("ProgressEvent\n");
+ // reschedule for next interval
+ schedule(curTick + interval);
+}
+
+
+const char *
+ProgressEvent::description()
+{
+ return "progress message";
+}
+
+/////////
+//
+// Periodic progress message support: print out a message every n
+// cycles so we know we're making forward progress.
+//
+/////////
+
+// Parameter space for execution address tracing options. Derive
+// from ParamContext so we can override checkParams() function.
+class ProgressParamContext : public ParamContext
+{
+ public:
+ ProgressParamContext(const string &_iniSection)
+ : ParamContext(_iniSection) {}
+ void checkParams();
+};
+
+ProgressParamContext progessMessageParams("progress");
+
+Param<Tick> progress_interval(&progessMessageParams, "cycle",
+ "cycle interval for progress messages");
+
+/* check execute options */
+void
+ProgressParamContext::checkParams()
+{
+ if (progress_interval.isValid())
+ new ProgressEvent(&mainEventQueue, progress_interval);
+}