main.cc (4081:80f1e833d118) | main.cc (4123:9c80390ea1bb) |
---|---|
1/* 2 * Copyright (c) 2000-2005 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; --- 11 unchanged lines hidden (view full) --- 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 * | 1/* 2 * Copyright (c) 2000-2005 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; --- 11 unchanged lines hidden (view full) --- 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 * Authors: Steve Raasch 29 * Nathan Binkert 30 * Steve Reinhardt | 28 * Authors: Nathan Binkert |
31 */ 32 | 29 */ 30 |
33/// 34/// @file sim/main.cc 35/// 36#include <Python.h> // must be before system headers... see Python docs | 31#include <Python.h> |
37 | 32 |
38#include <sys/types.h> 39#include <sys/stat.h> 40#include <errno.h> 41#include <libgen.h> 42#include <stdlib.h> 43#include <signal.h> 44#include <getopt.h> 45 46#include <list> | 33#include <iostream> |
47#include <string> | 34#include <string> |
48#include <vector> | |
49 | 35 |
50#include "base/callback.hh" 51#include "base/inifile.hh" | 36#include "base/cprintf.hh" |
52#include "base/misc.hh" | 37#include "base/misc.hh" |
53#include "base/output.hh" 54#include "base/pollevent.hh" 55#include "base/statistics.hh" 56#include "base/stats/output.hh" 57#include "base/str.hh" 58#include "base/time.hh" | |
59#include "config/pythonhome.hh" | 38#include "config/pythonhome.hh" |
60#include "cpu/base.hh" 61#include "cpu/smt.hh" 62#include "mem/mem_object.hh" 63#include "mem/port.hh" | |
64#include "python/swig/init.hh" 65#include "sim/async.hh" | 39#include "python/swig/init.hh" 40#include "sim/async.hh" |
66#include "sim/builder.hh" | |
67#include "sim/host.hh" | 41#include "sim/host.hh" |
68#include "sim/serialize.hh" 69#include "sim/sim_events.hh" 70#include "sim/sim_exit.hh" 71#include "sim/sim_object.hh" 72#include "sim/system.hh" 73#include "sim/stat_control.hh" 74#include "sim/stats.hh" | |
75#include "sim/root.hh" 76 77using namespace std; 78 | 42#include "sim/root.hh" 43 44using namespace std; 45 |
79// See async.h. 80volatile bool async_event = false; 81volatile bool async_dump = false; 82volatile bool async_dumpreset = false; 83volatile bool async_exit = false; 84volatile bool async_io = false; 85volatile bool async_alarm = false; 86volatile bool async_exception = false; 87 | |
88/// Stats signal handler. 89void 90dumpStatsHandler(int sigtype) 91{ 92 async_event = true; | 46/// Stats signal handler. 47void 48dumpStatsHandler(int sigtype) 49{ 50 async_event = true; |
93 async_dump = true; | 51 async_statdump = true; |
94} 95 96void 97dumprstStatsHandler(int sigtype) 98{ 99 async_event = true; | 52} 53 54void 55dumprstStatsHandler(int sigtype) 56{ 57 async_event = true; |
100 async_dumpreset = true; | 58 async_statdump = true; 59 async_statreset = true; |
101} 102 103/// Exit signal handler. 104void 105exitNowHandler(int sigtype) 106{ 107 async_event = true; 108 async_exit = true; 109} 110 111/// Abort signal handler. 112void 113abortHandler(int sigtype) 114{ | 60} 61 62/// Exit signal handler. 63void 64exitNowHandler(int sigtype) 65{ 66 async_event = true; 67 async_exit = true; 68} 69 70/// Abort signal handler. 71void 72abortHandler(int sigtype) 73{ |
115 cerr << "Program aborted at cycle " << curTick << endl; | 74 ccprintf(cerr, "Program aborted at cycle %d\n", curTick); |
116} 117 118int 119main(int argc, char **argv) 120{ 121 signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths 122 signal(SIGTRAP, SIG_IGN); 123 signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats --- 31 unchanged lines hidden (view full) --- 155 init_swig(); 156 157 PyRun_SimpleString("import m5.main"); 158 PyRun_SimpleString("m5.main.main()"); 159 160 // clean up Python intepreter. 161 Py_Finalize(); 162} | 75} 76 77int 78main(int argc, char **argv) 79{ 80 signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths 81 signal(SIGTRAP, SIG_IGN); 82 signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats --- 31 unchanged lines hidden (view full) --- 114 init_swig(); 115 116 PyRun_SimpleString("import m5.main"); 117 PyRun_SimpleString("m5.main.main()"); 118 119 // clean up Python intepreter. 120 Py_Finalize(); 121} |
163 164 165void 166setOutputDir(const string &dir) 167{ 168 simout.setDirectory(dir); 169} 170 171 172IniFile inifile; 173 174SimObject * 175createSimObject(const string &name) 176{ 177 return SimObjectClass::createObject(inifile, name); 178} 179 180 181/** 182 * Pointer to the Python function that maps names to SimObjects. 183 */ 184PyObject *resolveFunc = NULL; 185 186/** 187 * Convert a pointer to the Python object that SWIG wraps around a C++ 188 * SimObject pointer back to the actual C++ pointer. See main.i. 189 */ 190extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); 191 192 193SimObject * 194resolveSimObject(const string &name) 195{ 196 PyObject *pyPtr = PyEval_CallFunction(resolveFunc, "(s)", name.c_str()); 197 if (pyPtr == NULL) { 198 PyErr_Print(); 199 panic("resolveSimObject: failure on call to Python for %s", name); 200 } 201 202 SimObject *simObj = convertSwigSimObjectPtr(pyPtr); 203 if (simObj == NULL) 204 panic("resolveSimObject: failure on pointer conversion for %s", name); 205 206 return simObj; 207} 208 209 210/** 211 * Load config.ini into C++ database. Exported to Python via SWIG; 212 * invoked from m5.instantiate(). 213 */ 214void 215loadIniFile(PyObject *_resolveFunc) 216{ 217 resolveFunc = _resolveFunc; 218 configStream = simout.find("config.out"); 219 220 // The configuration database is now complete; start processing it. 221 inifile.load(simout.resolve("config.ini")); 222 223 // Initialize statistics database 224 Stats::initSimStats(); 225} 226 227 228/** 229 * Look up a MemObject port. Helper function for connectPorts(). 230 */ 231Port * 232lookupPort(SimObject *so, const std::string &name, int i) 233{ 234 MemObject *mo = dynamic_cast<MemObject *>(so); 235 if (mo == NULL) { 236 warn("error casting SimObject %s to MemObject", so->name()); 237 return NULL; 238 } 239 240 Port *p = mo->getPort(name, i); 241 if (p == NULL) 242 warn("error looking up port %s on object %s", name, so->name()); 243 return p; 244} 245 246 247/** 248 * Connect the described MemObject ports. Called from Python via SWIG. 249 */ 250int 251connectPorts(SimObject *o1, const std::string &name1, int i1, 252 SimObject *o2, const std::string &name2, int i2) 253{ 254 Port *p1 = lookupPort(o1, name1, i1); 255 Port *p2 = lookupPort(o2, name2, i2); 256 257 if (p1 == NULL || p2 == NULL) { 258 warn("connectPorts: port lookup error"); 259 return 0; 260 } 261 262 p1->setPeer(p2); 263 p2->setPeer(p1); 264 265 return 1; 266} 267 268/** 269 * Do final initialization steps after object construction but before 270 * start of simulation. 271 */ 272void 273finalInit() 274{ 275 // Do a second pass to finish initializing the sim objects 276 SimObject::initAll(); 277 278 // Restore checkpointed state, if any. 279#if 0 280 configHierarchy.unserializeSimObjects(); 281#endif 282 283 SimObject::regAllStats(); 284 285 // Check to make sure that the stats package is properly initialized 286 Stats::check(); 287 288 // Reset to put the stats in a consistent state. 289 Stats::reset(); 290 291 SimStartup(); 292} 293 294/** Simulate for num_cycles additional cycles. If num_cycles is -1 295 * (the default), do not limit simulation; some other event must 296 * terminate the loop. Exported to Python via SWIG. 297 * @return The SimLoopExitEvent that caused the loop to exit. 298 */ 299SimLoopExitEvent * 300simulate(Tick num_cycles = MaxTick) 301{ 302 warn("Entering event queue @ %d. Starting simulation...\n", curTick); 303 304 if (num_cycles < 0) 305 fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles); 306 else if (curTick + num_cycles < 0) //Overflow 307 num_cycles = MaxTick; 308 else 309 num_cycles = curTick + num_cycles; 310 311 Event *limit_event = schedExitSimLoop("simulate() limit reached", 312 num_cycles); 313 314 while (1) { 315 // there should always be at least one event (the SimLoopExitEvent 316 // we just scheduled) in the queue 317 assert(!mainEventQueue.empty()); 318 assert(curTick <= mainEventQueue.nextTick() && 319 "event scheduled in the past"); 320 321 // forward current cycle to the time of the first event on the 322 // queue 323 curTick = mainEventQueue.nextTick(); 324 Event *exit_event = mainEventQueue.serviceOne(); 325 if (exit_event != NULL) { 326 // hit some kind of exit event; return to Python 327 // event must be subclass of SimLoopExitEvent... 328 SimLoopExitEvent *se_event = dynamic_cast<SimLoopExitEvent *>(exit_event); 329 if (se_event == NULL) 330 panic("Bogus exit event class!"); 331 332 // if we didn't hit limit_event, delete it 333 if (se_event != limit_event) { 334 assert(limit_event->scheduled()); 335 limit_event->deschedule(); 336 delete limit_event; 337 } 338 339 return se_event; 340 } 341 342 if (async_event) { 343 async_event = false; 344 if (async_dump) { 345 async_dump = false; 346 Stats::StatEvent(true, false); 347 } 348 349 if (async_dumpreset) { 350 async_dumpreset = false; 351 Stats::StatEvent(true, true); 352 } 353 354 if (async_exit) { 355 async_exit = false; 356 exitSimLoop("user interrupt received"); 357 } 358 359 if (async_io || async_alarm) { 360 async_io = false; 361 async_alarm = false; 362 pollQueue.service(); 363 } 364 365 if (async_exception) { 366 async_exception = false; 367 return NULL; 368 } 369 } 370 } 371 372 // not reached... only exit is return on SimLoopExitEvent 373} 374 375Event * 376createCountedDrain() 377{ 378 return new CountedDrainEvent(); 379} 380 381void 382cleanupCountedDrain(Event *counted_drain) 383{ 384 CountedDrainEvent *event = 385 dynamic_cast<CountedDrainEvent *>(counted_drain); 386 if (event == NULL) { 387 fatal("Called cleanupCountedDrain() on an event that was not " 388 "a CountedDrainEvent."); 389 } 390 assert(event->getCount() == 0); 391 delete event; 392} 393 394void 395serializeAll(const std::string &cpt_dir) 396{ 397 Serializable::serializeAll(cpt_dir); 398} 399 400void 401unserializeAll(const std::string &cpt_dir) 402{ 403 Serializable::unserializeAll(cpt_dir); 404} 405 406/** 407 * Queue of C++ callbacks to invoke on simulator exit. 408 */ 409CallbackQueue& 410exitCallbacks() 411{ 412 static CallbackQueue theQueue; 413 return theQueue; 414} 415 416/** 417 * Register an exit callback. 418 */ 419void 420registerExitCallback(Callback *callback) 421{ 422 exitCallbacks().add(callback); 423} 424 425BaseCPU * 426convertToBaseCPUPtr(SimObject *obj) 427{ 428 BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj); 429 430 if (ptr == NULL) 431 warn("Casting to BaseCPU pointer failed"); 432 return ptr; 433} 434 435System * 436convertToSystemPtr(SimObject *obj) 437{ 438 System *ptr = dynamic_cast<System *>(obj); 439 440 if (ptr == NULL) 441 warn("Casting to System pointer failed"); 442 return ptr; 443} 444 445 446/** 447 * Do C++ simulator exit processing. Exported to SWIG to be invoked 448 * when simulator terminates via Python's atexit mechanism. 449 */ 450void 451doExitCleanup() 452{ 453 exitCallbacks().process(); 454 exitCallbacks().clear(); 455 456 cout.flush(); 457 458 // print simulation stats 459 Stats::dump(); 460} | |