sim_events.cc revision 2
1/* 2 * Copyright (c) 2003 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <string> 30 31#include "cpu.hh" 32#include "eventq.hh" 33#include "sim_events.hh" 34#include "sim_exit.hh" 35#include "sim_stats.hh" 36 37using namespace std; 38 39// 40// handle termination event 41// 42void 43SimExitEvent::process() 44{ 45 // This event does not autodelete because exitNow may be called, 46 // and the function will never be allowed to finish. 47 if (theQueue() == &mainEventQueue) { 48 string _cause = cause; 49 int _code = code; 50 delete this; 51 exitNow(_cause, _code); 52 } else { 53 new SimExitEvent(cause, code); 54 delete this; 55 } 56} 57 58 59const char * 60SimExitEvent::description() 61{ 62 return "simulation termination"; 63} 64 65 66// 67// constructor: automatically schedules at specified time 68// 69CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause, 70 Tick _when, int &_downCounter) 71 : Event(q), 72 cause(_cause), 73 downCounter(_downCounter) 74{ 75 // catch stupid mistakes 76 assert(downCounter > 0); 77 78 schedule(_when, 1000); 79} 80 81 82// 83// handle termination event 84// 85void 86CountedExitEvent::process() 87{ 88 if (--downCounter == 0) { 89 new SimExitEvent(cause, 1); 90 } 91} 92 93 94const char * 95CountedExitEvent::description() 96{ 97 return "counted exit"; 98} 99 100 101void 102DumpStatsEvent::process() 103{ 104 dumpStats(); 105} 106 107const char * 108DumpStatsEvent::description() 109{ 110 return "stats dump"; 111} 112 113 114#ifdef CHECK_SWAP_CYCLES 115new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES); 116#endif 117 118void 119CheckSwapEvent::process() 120{ 121 /* Check the amount of free swap space */ 122 long swap; 123 124 /* returns free swap in KBytes */ 125 swap = proc_info("/proc/meminfo", "SwapFree:"); 126 127 if (swap < 1000) 128 ccprintf(cerr, "\a\a\aWarning! Swap space is low (%d)\n", swap); 129 130 if (swap < 100) { 131 cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n"; 132 new SimExitEvent("Lack of swap space"); 133 } 134 135 schedule(curTick + interval); 136} 137 138const char * 139CheckSwapEvent::description() 140{ 141 return "check swap"; 142} 143 144 145class DumpStatsContext : public ParamContext 146{ 147 public: 148 DumpStatsContext(const string &_iniSection) 149 : ParamContext(_iniSection) {} 150 void checkParams(); 151}; 152 153DumpStatsContext dumpStatsParams("stats"); 154 155VectorParam<Tick> dump_cycle(&dumpStatsParams, "dump_cycles", 156 "cycles on which to dump stats"); 157 158void 159DumpStatsContext::checkParams() 160{ 161 if (dump_cycle.isValid()) { 162 vector<Tick> &cycles = dump_cycle; 163 164 vector<Tick>::iterator i = cycles.begin(); 165 vector<Tick>::iterator end = cycles.end(); 166 167 for (; i < end; ++i) 168 new DumpStatsEvent(*i); 169 } 170} 171 172/////////////////////////////////////////////////// 173// 174// Simulation termination parameters 175// 176/////////////////////////////////////////////////// 177 178class TermParamContext : public ParamContext 179{ 180 public: 181 TermParamContext(const string &_iniSection) 182 : ParamContext(_iniSection) {} 183 void checkParams(); 184}; 185 186TermParamContext simTerminationParams("max"); 187 188Param<Tick> max_cycle(&simTerminationParams, "cycle", 189 "maximum number of cycles to execute"); 190 191void 192TermParamContext::checkParams() 193{ 194 // if a max cycle count was specified, put a termination event on 195 // the event queue at that point 196 if (max_cycle.isValid()) 197 new SimExitEvent(max_cycle, "reached maximum cycle count"); 198} 199 200// 201// Progress event: print out cycle every so often so we know we're 202// making forward progress. 203// 204class ProgressEvent : public Event 205{ 206 protected: 207 Tick interval; 208 209 public: 210 ProgressEvent(EventQueue *q, Tick interval); 211 212 void process(); // process event 213 virtual const char *description(); 214}; 215 216// 217// constructor: schedule at specified time 218// 219ProgressEvent::ProgressEvent(EventQueue *q, Tick _interval) 220 : Event(q), interval(_interval) 221{ 222 schedule(interval); 223} 224 225// 226// handle progress event: print message and reschedule 227// 228void 229ProgressEvent::process() 230{ 231 DPRINTFN("ProgressEvent\n"); 232 // reschedule for next interval 233 schedule(curTick + interval); 234} 235 236 237const char * 238ProgressEvent::description() 239{ 240 return "progress message"; 241} 242 243///////// 244// 245// Periodic progress message support: print out a message every n 246// cycles so we know we're making forward progress. 247// 248///////// 249 250// Parameter space for execution address tracing options. Derive 251// from ParamContext so we can override checkParams() function. 252class ProgressParamContext : public ParamContext 253{ 254 public: 255 ProgressParamContext(const string &_iniSection) 256 : ParamContext(_iniSection) {} 257 void checkParams(); 258}; 259 260ProgressParamContext progessMessageParams("progress"); 261 262Param<Tick> progress_interval(&progessMessageParams, "cycle", 263 "cycle interval for progress messages"); 264 265/* check execute options */ 266void 267ProgressParamContext::checkParams() 268{ 269 if (progress_interval.isValid()) 270 new ProgressEvent(&mainEventQueue, progress_interval); 271} 272