diff options
Diffstat (limited to 'sim/sim_events.cc')
-rw-r--r-- | sim/sim_events.cc | 271 |
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); +} |