sim_events.cc revision 56
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/full_cpu/cpu.hh" 32#include "sim/eventq.hh" 33#include "base/hostinfo.hh" 34#include "sim/sim_events.hh" 35#include "sim/sim_exit.hh" 36#include "sim/sim_stats.hh" 37 38using namespace std; 39 40// 41// handle termination event 42// 43void 44SimExitEvent::process() 45{ 46 // This event does not autodelete because exitNow may be called, 47 // and the function will never be allowed to finish. 48 if (theQueue() == &mainEventQueue) { 49 string _cause = cause; 50 int _code = code; 51 delete this; 52 exitNow(_cause, _code); 53 } else { 54 new SimExitEvent(cause, code); 55 delete this; 56 } 57} 58 59 60const char * 61SimExitEvent::description() 62{ 63 return "simulation termination"; 64} 65 66 67// 68// constructor: automatically schedules at specified time 69// 70CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause, 71 Tick _when, int &_downCounter) 72 : Event(q), 73 cause(_cause), 74 downCounter(_downCounter) 75{ 76 // catch stupid mistakes 77 assert(downCounter > 0); 78 79 schedule(_when, 1000); 80} 81 82 83// 84// handle termination event 85// 86void 87CountedExitEvent::process() 88{ 89 if (--downCounter == 0) { 90 new SimExitEvent(cause, 1); 91 } 92} 93 94 95const char * 96CountedExitEvent::description() 97{ 98 return "counted exit"; 99} 100 101 102void 103DumpStatsEvent::process() 104{ 105 dumpStats(); 106} 107 108const char * 109DumpStatsEvent::description() 110{ 111 return "stats dump"; 112} 113 114 115#ifdef CHECK_SWAP_CYCLES 116new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES); 117#endif 118 119void 120CheckSwapEvent::process() 121{ 122 /* Check the amount of free swap space */ 123 long swap; 124 125 /* returns free swap in KBytes */ 126 swap = procInfo("/proc/meminfo", "SwapFree:"); 127 128 if (swap < 1000) 129 ccprintf(cerr, "\a\a\aWarning! Swap space is low (%d)\n", swap); 130 131 if (swap < 100) { 132 cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n"; 133 new SimExitEvent("Lack of swap space"); 134 } 135 136 schedule(curTick + interval); 137} 138 139const char * 140CheckSwapEvent::description() 141{ 142 return "check swap"; 143} 144 145 146class DumpStatsContext : public ParamContext 147{ 148 public: 149 DumpStatsContext(const string &_iniSection) 150 : ParamContext(_iniSection) {} 151 void checkParams(); 152}; 153 154DumpStatsContext dumpStatsParams("stats"); 155 156VectorParam<Tick> dump_cycle(&dumpStatsParams, "dump_cycles", 157 "cycles on which to dump stats"); 158 159void 160DumpStatsContext::checkParams() 161{ 162 if (dump_cycle.isValid()) { 163 vector<Tick> &cycles = dump_cycle; 164 165 vector<Tick>::iterator i = cycles.begin(); 166 vector<Tick>::iterator end = cycles.end(); 167 168 for (; i < end; ++i) 169 new DumpStatsEvent(*i); 170 } 171} 172 173/////////////////////////////////////////////////// 174// 175// Simulation termination parameters 176// 177/////////////////////////////////////////////////// 178 179class TermParamContext : public ParamContext 180{ 181 public: 182 TermParamContext(const string &_iniSection) 183 : ParamContext(_iniSection) {} 184 void checkParams(); 185}; 186 187TermParamContext simTerminationParams("max"); 188 189Param<Tick> max_cycle(&simTerminationParams, "cycle", 190 "maximum number of cycles to execute"); 191 192void 193TermParamContext::checkParams() 194{ 195 // if a max cycle count was specified, put a termination event on 196 // the event queue at that point 197 if (max_cycle.isValid()) 198 new SimExitEvent(max_cycle, "reached maximum cycle count"); 199} 200 201// 202// Progress event: print out cycle every so often so we know we're 203// making forward progress. 204// 205class ProgressEvent : public Event 206{ 207 protected: 208 Tick interval; 209 210 public: 211 ProgressEvent(EventQueue *q, Tick interval); 212 213 void process(); // process event 214 virtual const char *description(); 215}; 216 217// 218// constructor: schedule at specified time 219// 220ProgressEvent::ProgressEvent(EventQueue *q, Tick _interval) 221 : Event(q), interval(_interval) 222{ 223 schedule(interval); 224} 225 226// 227// handle progress event: print message and reschedule 228// 229void 230ProgressEvent::process() 231{ 232 DPRINTFN("ProgressEvent\n"); 233 // reschedule for next interval 234 schedule(curTick + interval); 235} 236 237 238const char * 239ProgressEvent::description() 240{ 241 return "progress message"; 242} 243 244///////// 245// 246// Periodic progress message support: print out a message every n 247// cycles so we know we're making forward progress. 248// 249///////// 250 251// Parameter space for execution address tracing options. Derive 252// from ParamContext so we can override checkParams() function. 253class ProgressParamContext : public ParamContext 254{ 255 public: 256 ProgressParamContext(const string &_iniSection) 257 : ParamContext(_iniSection) {} 258 void checkParams(); 259}; 260 261ProgressParamContext progessMessageParams("progress"); 262 263Param<Tick> progress_interval(&progessMessageParams, "cycle", 264 "cycle interval for progress messages"); 265 266/* check execute options */ 267void 268ProgressParamContext::checkParams() 269{ 270 if (progress_interval.isValid()) 271 new ProgressEvent(&mainEventQueue, progress_interval); 272} 273