sim_events.cc revision 396
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 "sim/param.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// constructor: automatically schedules at specified time 68// 69CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause, 70 Tick _when, int &_downCounter) 71 : Event(q, Sim_Exit_Pri), 72 cause(_cause), 73 downCounter(_downCounter) 74{ 75 // catch stupid mistakes 76 assert(downCounter > 0); 77 78 schedule(_when); 79} 80 81 82// 83// handle termination event 84// 85void 86CountedExitEvent::process() 87{ 88 if (--downCounter == 0) { 89 new SimExitEvent(cause, 0); 90 } 91} 92 93 94const char * 95CountedExitEvent::description() 96{ 97 return "counted exit"; 98} 99 100#ifdef CHECK_SWAP_CYCLES 101new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES); 102#endif 103 104void 105CheckSwapEvent::process() 106{ 107 /* Check the amount of free swap space */ 108 long swap; 109 110 /* returns free swap in KBytes */ 111 swap = procInfo("/proc/meminfo", "SwapFree:"); 112 113 if (swap < 1000) 114 ccprintf(cerr, "\a\a\aWarning! Swap space is low (%d)\n", swap); 115 116 if (swap < 100) { 117 cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n"; 118 new SimExitEvent("Lack of swap space"); 119 } 120 121 schedule(curTick + interval); 122} 123 124const char * 125CheckSwapEvent::description() 126{ 127 return "check swap"; 128} 129 130 131/////////////////////////////////////////////////// 132// 133// Simulation termination parameters 134// 135/////////////////////////////////////////////////// 136 137class TermParamContext : public ParamContext 138{ 139 public: 140 TermParamContext(const string &_iniSection) 141 : ParamContext(_iniSection) {} 142 void checkParams(); 143}; 144 145TermParamContext simTerminationParams("max"); 146 147Param<Tick> max_cycle(&simTerminationParams, "cycle", 148 "maximum number of cycles to execute"); 149 150void 151TermParamContext::checkParams() 152{ 153 // if a max cycle count was specified, put a termination event on 154 // the event queue at that point 155 if (max_cycle.isValid()) 156 new SimExitEvent(max_cycle, "reached maximum cycle count"); 157} 158 159// 160// Progress event: print out cycle every so often so we know we're 161// making forward progress. 162// 163class ProgressEvent : public Event 164{ 165 protected: 166 Tick interval; 167 168 public: 169 ProgressEvent(EventQueue *q, Tick interval); 170 171 void process(); // process event 172 virtual const char *description(); 173}; 174 175// 176// constructor: schedule at specified time 177// 178ProgressEvent::ProgressEvent(EventQueue *q, Tick _interval) 179 : Event(q), interval(_interval) 180{ 181 schedule(interval); 182} 183 184// 185// handle progress event: print message and reschedule 186// 187void 188ProgressEvent::process() 189{ 190 DPRINTFN("ProgressEvent\n"); 191 // reschedule for next interval 192 schedule(curTick + interval); 193} 194 195 196const char * 197ProgressEvent::description() 198{ 199 return "progress message"; 200} 201 202///////// 203// 204// Periodic progress message support: print out a message every n 205// cycles so we know we're making forward progress. 206// 207///////// 208 209// Parameter space for execution address tracing options. Derive 210// from ParamContext so we can override checkParams() function. 211class ProgressParamContext : public ParamContext 212{ 213 public: 214 ProgressParamContext(const string &_iniSection) 215 : ParamContext(_iniSection) {} 216 void checkParams(); 217}; 218 219ProgressParamContext progessMessageParams("progress"); 220 221Param<Tick> progress_interval(&progessMessageParams, "cycle", 222 "cycle interval for progress messages"); 223 224/* check execute options */ 225void 226ProgressParamContext::checkParams() 227{ 228 if (progress_interval.isValid()) 229 new ProgressEvent(&mainEventQueue, progress_interval); 230} 231