sim_events.cc revision 2
19340SAndreas.Sandberg@arm.com/* 29340SAndreas.Sandberg@arm.com * Copyright (c) 2003 The Regents of The University of Michigan 39340SAndreas.Sandberg@arm.com * All rights reserved. 49340SAndreas.Sandberg@arm.com * 59340SAndreas.Sandberg@arm.com * Redistribution and use in source and binary forms, with or without 69340SAndreas.Sandberg@arm.com * modification, are permitted provided that the following conditions are 79340SAndreas.Sandberg@arm.com * met: redistributions of source code must retain the above copyright 89340SAndreas.Sandberg@arm.com * notice, this list of conditions and the following disclaimer; 99340SAndreas.Sandberg@arm.com * redistributions in binary form must reproduce the above copyright 109340SAndreas.Sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 119340SAndreas.Sandberg@arm.com * documentation and/or other materials provided with the distribution; 129340SAndreas.Sandberg@arm.com * neither the name of the copyright holders nor the names of its 139340SAndreas.Sandberg@arm.com * contributors may be used to endorse or promote products derived from 149340SAndreas.Sandberg@arm.com * this software without specific prior written permission. 159340SAndreas.Sandberg@arm.com * 169340SAndreas.Sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179340SAndreas.Sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189340SAndreas.Sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199340SAndreas.Sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209340SAndreas.Sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219340SAndreas.Sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229340SAndreas.Sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239340SAndreas.Sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249340SAndreas.Sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259340SAndreas.Sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269340SAndreas.Sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279340SAndreas.Sandberg@arm.com */ 289340SAndreas.Sandberg@arm.com 299340SAndreas.Sandberg@arm.com#include <string> 309340SAndreas.Sandberg@arm.com 319340SAndreas.Sandberg@arm.com#include "cpu.hh" 329340SAndreas.Sandberg@arm.com#include "eventq.hh" 339340SAndreas.Sandberg@arm.com#include "sim_events.hh" 349340SAndreas.Sandberg@arm.com#include "sim_exit.hh" 359340SAndreas.Sandberg@arm.com#include "sim_stats.hh" 369340SAndreas.Sandberg@arm.com 379340SAndreas.Sandberg@arm.comusing namespace std; 389340SAndreas.Sandberg@arm.com 399340SAndreas.Sandberg@arm.com// 409340SAndreas.Sandberg@arm.com// handle termination event 419340SAndreas.Sandberg@arm.com// 429340SAndreas.Sandberg@arm.comvoid 439340SAndreas.Sandberg@arm.comSimExitEvent::process() 449340SAndreas.Sandberg@arm.com{ 459340SAndreas.Sandberg@arm.com // This event does not autodelete because exitNow may be called, 469340SAndreas.Sandberg@arm.com // and the function will never be allowed to finish. 479340SAndreas.Sandberg@arm.com if (theQueue() == &mainEventQueue) { 489340SAndreas.Sandberg@arm.com string _cause = cause; 499340SAndreas.Sandberg@arm.com int _code = code; 509340SAndreas.Sandberg@arm.com delete this; 519340SAndreas.Sandberg@arm.com exitNow(_cause, _code); 529340SAndreas.Sandberg@arm.com } else { 539340SAndreas.Sandberg@arm.com new SimExitEvent(cause, code); 549340SAndreas.Sandberg@arm.com delete this; 559340SAndreas.Sandberg@arm.com } 569340SAndreas.Sandberg@arm.com} 579340SAndreas.Sandberg@arm.com 589340SAndreas.Sandberg@arm.com 599340SAndreas.Sandberg@arm.comconst char * 609340SAndreas.Sandberg@arm.comSimExitEvent::description() 619340SAndreas.Sandberg@arm.com{ 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