main.cc revision 294
12SN/A/*
21762SN/A * Copyright (c) 2003 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu///
302665Ssaidi@eecs.umich.edu/// @file sim/main.cc
312SN/A///
322SN/A#include <sys/types.h>
332SN/A#include <sys/stat.h>
342SN/A#include <stdlib.h>
352SN/A#include <signal.h>
362655Sstever@eecs.umich.edu
372655Sstever@eecs.umich.edu#include <string>
382SN/A#include <vector>
392SN/A
401399SN/A#include "base/copyright.hh"
411396SN/A#include "base/inifile.hh"
422SN/A#include "base/misc.hh"
432SN/A#include "base/pollevent.hh"
442729Ssaidi@eecs.umich.edu#include "base/statistics.hh"
452SN/A#include "cpu/base_cpu.hh"
461310SN/A#include "cpu/full_cpu/smt.hh"
472SN/A#include "sim/async.hh"
482SN/A#include "sim/builder.hh"
492SN/A#include "sim/configfile.hh"
502667Sstever@eecs.umich.edu#include "sim/host.hh"
5156SN/A#include "sim/sim_events.hh"
52146SN/A#include "sim/sim_exit.hh"
531388SN/A#include "sim/sim_object.hh"
5456SN/A#include "sim/sim_stats.hh"
5556SN/A#include "sim/sim_time.hh"
561311SN/A
57400SN/Ausing namespace std;
581717SN/A
591717SN/A// See async.h.
602738Sstever@eecs.umich.eduvolatile bool async_event = false;
612738Sstever@eecs.umich.eduvolatile bool async_dump = false;
62146SN/Avolatile bool async_exit = false;
63146SN/Avolatile bool async_io = false;
64146SN/Avolatile bool async_alarm = false;
652797Sktlim@umich.edu
6656SN/A/// Stats signal handler.
6756SN/Avoid
6856SN/AdumpStatsHandler(int sigtype)
69695SN/A{
70695SN/A    async_event = true;
711696SN/A    async_dump = true;
722SN/A}
732SN/A
742SN/A/// Exit signal handler.
752SN/Avoid
762SN/AexitNowHandler(int sigtype)
772SN/A{
78329SN/A    async_event = true;
792SN/A    async_exit = true;
802SN/A}
812SN/A
822SN/A/// Simulator executable name
832SN/Aconst char *myProgName = "";
842SN/A
852SN/A/// Show brief help message.
862SN/Astatic void
872SN/AshowBriefHelp(ostream &out)
882SN/A{
892SN/A    out << "Usage: " << myProgName
902SN/A         << " [-hn] [-Dname[=def]] [-Uname] [-I[dir]] "
91329SN/A         << "[--<section>:<param>=<value>] [<config file> ...]" << endl
92329SN/A         << "   -h: print long help (including parameter listing)" << endl
93329SN/A         << "   -n: don't load default.ini" << endl
94329SN/A         << "   -u: don't quit on unreferenced parameters" << endl
95329SN/A         << "   -D,-U,-I: passed to cpp for preprocessing .ini files" << endl;
96329SN/A}
97329SN/A
982SN/A/// Show verbose help message.  Includes parameter listing from
992SN/A/// showBriefHelp(), plus an exhaustive list of ini-file parameters
1002SN/A/// and SimObjects (with their parameters).
1012SN/Astatic void
1022SN/AshowLongHelp(ostream &out)
1032SN/A{
1042SN/A    showBriefHelp(out);
1052SN/A
106764SN/A    out << endl
107764SN/A        << endl
108764SN/A        << "-----------------" << endl
109764SN/A        << "Global Parameters" << endl
110764SN/A        << "-----------------" << endl
111764SN/A        << endl;
112764SN/A
113764SN/A    ParamContext::describeAllContexts(out);
114764SN/A
115764SN/A    out << endl
116764SN/A        << endl
117764SN/A        << "-----------------" << endl
1182729Ssaidi@eecs.umich.edu        << "Simulator Objects" << endl
1192729Ssaidi@eecs.umich.edu        << "-----------------" << endl
1202729Ssaidi@eecs.umich.edu        << endl;
1212729Ssaidi@eecs.umich.edu
1222729Ssaidi@eecs.umich.edu    SimObjectClass::describeAllClasses(out);
1232729Ssaidi@eecs.umich.edu}
1242729Ssaidi@eecs.umich.edu
1252729Ssaidi@eecs.umich.edu/// Print welcome message.
1262729Ssaidi@eecs.umich.edustatic void
1272729Ssaidi@eecs.umich.edusayHello(ostream &out)
1282729Ssaidi@eecs.umich.edu{
1292729Ssaidi@eecs.umich.edu    extern const char *compileDate;	// from date.cc
1302729Ssaidi@eecs.umich.edu
1312729Ssaidi@eecs.umich.edu    ccprintf(out, "M5 Simulator System\n");
1322729Ssaidi@eecs.umich.edu    // display copyright
1332729Ssaidi@eecs.umich.edu    ccprintf(out, "%s\n", briefCopyright);
1342729Ssaidi@eecs.umich.edu    ccprintf(out, "M5 compiled on %d\n", compileDate);
1352729Ssaidi@eecs.umich.edu
1362729Ssaidi@eecs.umich.edu    char *host = getenv("HOSTNAME");
1372729Ssaidi@eecs.umich.edu    if (!host)
1382729Ssaidi@eecs.umich.edu        host = getenv("HOST");
1392737Ssaidi@eecs.umich.edu
1402737Ssaidi@eecs.umich.edu    if (host)
1412737Ssaidi@eecs.umich.edu        ccprintf(out, "M5 executing on %s\n", host);
1422729Ssaidi@eecs.umich.edu
1432729Ssaidi@eecs.umich.edu    ccprintf(out, "M5 simulation started %s\n", Time::start);
1442729Ssaidi@eecs.umich.edu}
1452SN/A
1462667Sstever@eecs.umich.edu///
1472667Sstever@eecs.umich.edu/// Echo the command line for posterity in such a way that it can be
1482667Sstever@eecs.umich.edu/// used to rerun the same simulation (given the same .ini files).
1492667Sstever@eecs.umich.edu///
1502667Sstever@eecs.umich.edustatic void
1512667Sstever@eecs.umich.eduechoCommandLine(int argc, char **argv, ostream &out)
1521388SN/A{
1532667Sstever@eecs.umich.edu    out << "command line: " << argv[0];
1542SN/A    for (int i = 1; i < argc; i++) {
1552667Sstever@eecs.umich.edu        string arg(argv[i]);
1562SN/A
1572667Sstever@eecs.umich.edu        out << ' ';
1582667Sstever@eecs.umich.edu
1592667Sstever@eecs.umich.edu        // If the arg contains spaces, we need to quote it.
1602667Sstever@eecs.umich.edu        // The rest of this is overkill to make it look purty.
1612667Sstever@eecs.umich.edu
1622SN/A        // print dashes first outside quotes
1632667Sstever@eecs.umich.edu        int non_dash_pos = arg.find_first_not_of("-");
1642667Sstever@eecs.umich.edu        out << arg.substr(0, non_dash_pos);	// print dashes
1652667Sstever@eecs.umich.edu        string body = arg.substr(non_dash_pos);	// the rest
1662SN/A
1672667Sstever@eecs.umich.edu        // if it's an assignment, handle the lhs & rhs separately
1682667Sstever@eecs.umich.edu        int eq_pos = body.find("=");
1692667Sstever@eecs.umich.edu        if (eq_pos == string::npos) {
1702SN/A            out << quote(body);
1712SN/A        }
1722763Sstever@eecs.umich.edu        else {
1732SN/A            string lhs(body.substr(0, eq_pos));
1742SN/A            string rhs(body.substr(eq_pos + 1));
1752SN/A
1762SN/A            out << quote(lhs) << "=" << quote(rhs);
1772729Ssaidi@eecs.umich.edu        }
1782729Ssaidi@eecs.umich.edu    }
1792729Ssaidi@eecs.umich.edu    out << endl << endl;
1802667Sstever@eecs.umich.edu}
1812SN/A
1822SN/A
1832SN/A///
184329SN/A/// The simulator configuration database.  This is the union of all
185329SN/A/// specified .ini files.  This shouldn't need to be visible outside
186329SN/A/// this file, as it is passed as a parameter to all the param-parsing
187764SN/A/// routines.
1882SN/A///
1892655Sstever@eecs.umich.edustatic IniFile simConfigDB;
1902667Sstever@eecs.umich.edu
1912667Sstever@eecs.umich.edu/// Check for a default.ini file and load it if necessary.
1922667Sstever@eecs.umich.edustatic void
1932667Sstever@eecs.umich.eduhandleDefaultIni(bool &loadIt, vector<char *> &cppArgs)
1942667Sstever@eecs.umich.edu{
1952667Sstever@eecs.umich.edu    struct stat sb;
1962729Ssaidi@eecs.umich.edu
1972667Sstever@eecs.umich.edu    if (loadIt) {
1982729Ssaidi@eecs.umich.edu        if (stat("default.ini", &sb) == 0) {
1992729Ssaidi@eecs.umich.edu            if (!simConfigDB.loadCPP("default.ini", cppArgs)) {
2002729Ssaidi@eecs.umich.edu                cout << "Error processing file default.ini" << endl;
2012729Ssaidi@eecs.umich.edu                exit(1);
2022729Ssaidi@eecs.umich.edu            }
2032729Ssaidi@eecs.umich.edu        }
2042729Ssaidi@eecs.umich.edu
2052729Ssaidi@eecs.umich.edu        // set this whether it actually was found or not, so we don't
2062729Ssaidi@eecs.umich.edu        // bother to check again next time
2072667Sstever@eecs.umich.edu        loadIt = false;
2082729Ssaidi@eecs.umich.edu    }
2092667Sstever@eecs.umich.edu}
2102667Sstever@eecs.umich.edu
2112667Sstever@eecs.umich.edu
2122667Sstever@eecs.umich.edu/// M5 entry point.
2132667Sstever@eecs.umich.eduint
2142667Sstever@eecs.umich.edumain(int argc, char **argv)
2152667Sstever@eecs.umich.edu{
2162667Sstever@eecs.umich.edu    // Save off program name
2172667Sstever@eecs.umich.edu    myProgName = argv[0];
2182667Sstever@eecs.umich.edu
2192667Sstever@eecs.umich.edu    signal(SIGFPE, SIG_IGN);		// may occur on misspeculated paths
2202667Sstever@eecs.umich.edu    signal(SIGPIPE, SIG_IGN);
2212667Sstever@eecs.umich.edu    signal(SIGTRAP, SIG_IGN);
2222667Sstever@eecs.umich.edu    signal(SIGUSR1, dumpStatsHandler);	// dump intermediate stats
2232667Sstever@eecs.umich.edu    signal(SIGINT, exitNowHandler);	// dump final stats and exit
2242667Sstever@eecs.umich.edu
2252729Ssaidi@eecs.umich.edu    sayHello(cerr);
2262729Ssaidi@eecs.umich.edu
2272729Ssaidi@eecs.umich.edu    // Initialize statistics database
2282667Sstever@eecs.umich.edu    initBaseStats();
2292667Sstever@eecs.umich.edu
2302667Sstever@eecs.umich.edu    vector<char *> cppArgs;
2312667Sstever@eecs.umich.edu
2322667Sstever@eecs.umich.edu    // Should we use default.ini if it exists?  By default, yes.  (Use
2332667Sstever@eecs.umich.edu    // -n to override.)
2342667Sstever@eecs.umich.edu    bool loadDefaultIni = true;
2352667Sstever@eecs.umich.edu
2362667Sstever@eecs.umich.edu    // Should we quit if there are unreferenced parameters?  By
2372729Ssaidi@eecs.umich.edu    // default, yes... it's a good way of catching typos in
2382729Ssaidi@eecs.umich.edu    // section/parameter names (which otherwise go by silently).  Use
2392729Ssaidi@eecs.umich.edu    // -u to override.
2402729Ssaidi@eecs.umich.edu    bool quitOnUnreferenced = true;
2412729Ssaidi@eecs.umich.edu
2422667Sstever@eecs.umich.edu    // Parse command-line options.  The tricky part here is figuring
2432667Sstever@eecs.umich.edu    // out whether to look for & load default.ini, and if needed,
2442667Sstever@eecs.umich.edu    // doing so at the right time w.r.t. processing the other
2452667Sstever@eecs.umich.edu    // parameters.
2462667Sstever@eecs.umich.edu    //
2472667Sstever@eecs.umich.edu    // Since most of the complex options are handled through the
2482667Sstever@eecs.umich.edu    // config database, we don't mess with getopts, and just parse
2492667Sstever@eecs.umich.edu    // manually.
2502667Sstever@eecs.umich.edu    for (int i = 1; i < argc; ++i) {
2512667Sstever@eecs.umich.edu        char *arg_str = argv[i];
2522667Sstever@eecs.umich.edu
2532667Sstever@eecs.umich.edu        // if arg starts with '-', parse as option,
2542667Sstever@eecs.umich.edu        // else treat it as a configuration file name and load it
2552667Sstever@eecs.umich.edu        if (arg_str[0] == '-') {
2562667Sstever@eecs.umich.edu
2572667Sstever@eecs.umich.edu            // switch on second char
2582667Sstever@eecs.umich.edu            switch (arg_str[1]) {
2592667Sstever@eecs.umich.edu              case 'h':
2602667Sstever@eecs.umich.edu                // -h: show help
2612655Sstever@eecs.umich.edu                showLongHelp(cerr);
2622655Sstever@eecs.umich.edu                exit(1);
2631311SN/A
2642763Sstever@eecs.umich.edu              case 'n':
2652763Sstever@eecs.umich.edu                // -n: don't load default.ini
2661703SN/A                if (!loadDefaultIni) {
2672667Sstever@eecs.umich.edu                    cerr << "Warning: -n option needs to precede any "
2682667Sstever@eecs.umich.edu                         << "explicit configuration file name " << endl
2692667Sstever@eecs.umich.edu                         << "         or command-line configuration parameter."
2702667Sstever@eecs.umich.edu                         << endl;
2712667Sstever@eecs.umich.edu                }
2722667Sstever@eecs.umich.edu                loadDefaultIni = false;
2732667Sstever@eecs.umich.edu                break;
2742667Sstever@eecs.umich.edu
2751703SN/A              case 'u':
2762667Sstever@eecs.umich.edu                // -u: don't quit on unreferenced parameters
2772667Sstever@eecs.umich.edu                quitOnUnreferenced = false;
2782667Sstever@eecs.umich.edu                break;
2792667Sstever@eecs.umich.edu
2802667Sstever@eecs.umich.edu              case 'D':
2812SN/A              case 'U':
2822667Sstever@eecs.umich.edu              case 'I':
2832667Sstever@eecs.umich.edu                // cpp options: record & pass to cpp.  Note that these
2842667Sstever@eecs.umich.edu                // cannot have spaces, i.e., '-Dname=val' is OK, but
2852667Sstever@eecs.umich.edu                // '-D name=val' is not.  I don't consider this a
2862667Sstever@eecs.umich.edu                // problem, since even though gnu cpp accepts the
2872667Sstever@eecs.umich.edu                // latter, other cpp implementations do not (Tru64,
2882667Sstever@eecs.umich.edu                // for one).
2892667Sstever@eecs.umich.edu                cppArgs.push_back(arg_str);
2902667Sstever@eecs.umich.edu                break;
2912667Sstever@eecs.umich.edu
2922667Sstever@eecs.umich.edu              case '-':
2932667Sstever@eecs.umich.edu                // command-line configuration parameter:
2942667Sstever@eecs.umich.edu                // '--<section>:<parameter>=<value>'
2952667Sstever@eecs.umich.edu
2962667Sstever@eecs.umich.edu                // Load default.ini if necessary -- see comment in
2972667Sstever@eecs.umich.edu                // else clause below.
2982667Sstever@eecs.umich.edu                handleDefaultIni(loadDefaultIni, cppArgs);
2992667Sstever@eecs.umich.edu
3002655Sstever@eecs.umich.edu                if (!simConfigDB.add(arg_str + 2)) {
3012667Sstever@eecs.umich.edu                    // parse error
3021388SN/A                    ccprintf(cerr,
3032762Sstever@eecs.umich.edu                             "Could not parse configuration argument '%s'\n"
3042762Sstever@eecs.umich.edu                             "Expecting --<section>:<parameter>=<value>\n",
3052762Sstever@eecs.umich.edu                             arg_str);
3062762Sstever@eecs.umich.edu                    exit(0);
3072762Sstever@eecs.umich.edu                }
3082762Sstever@eecs.umich.edu                break;
3092762Sstever@eecs.umich.edu
3102762Sstever@eecs.umich.edu              default:
3112738Sstever@eecs.umich.edu                showBriefHelp(cerr);
3122667Sstever@eecs.umich.edu                ccprintf(cerr, "Fatal: invalid argument '%s'\n", arg_str);
3132738Sstever@eecs.umich.edu                exit(0);
3142738Sstever@eecs.umich.edu            }
3152738Sstever@eecs.umich.edu        }
3162738Sstever@eecs.umich.edu        else {
3172738Sstever@eecs.umich.edu            // no '-', treat as config file name
3182738Sstever@eecs.umich.edu
3192738Sstever@eecs.umich.edu            // If we haven't loaded default.ini yet, and we want to,
3202738Sstever@eecs.umich.edu            // now is the time.  Can't do it sooner because we need to
3212738Sstever@eecs.umich.edu            // look for '-n', can't do it later since we want
3222738Sstever@eecs.umich.edu            // default.ini loaded first (so that any other settings
3232738Sstever@eecs.umich.edu            // override it).
3242738Sstever@eecs.umich.edu            handleDefaultIni(loadDefaultIni, cppArgs);
3252738Sstever@eecs.umich.edu
3262738Sstever@eecs.umich.edu            if (!simConfigDB.loadCPP(arg_str, cppArgs)) {
3272738Sstever@eecs.umich.edu                cprintf("Error processing file %s\n", arg_str);
3282738Sstever@eecs.umich.edu                exit(1);
3292738Sstever@eecs.umich.edu            }
3302738Sstever@eecs.umich.edu        }
3312738Sstever@eecs.umich.edu    }
3322738Sstever@eecs.umich.edu
3332738Sstever@eecs.umich.edu    // Final check for default.ini, in case no config files or
3342738Sstever@eecs.umich.edu    // command-line config parameters were given.
3352738Sstever@eecs.umich.edu    handleDefaultIni(loadDefaultIni, cppArgs);
3362738Sstever@eecs.umich.edu
3372738Sstever@eecs.umich.edu    // The configuration database is now complete; start processing it.
3382738Sstever@eecs.umich.edu
3392738Sstever@eecs.umich.edu    // Parse and check all non-config-hierarchy parameters.
3402738Sstever@eecs.umich.edu    ParamContext::parseAllContexts(simConfigDB);
3412738Sstever@eecs.umich.edu    ParamContext::checkAllContexts();
3422738Sstever@eecs.umich.edu
3432738Sstever@eecs.umich.edu    // Print header info into stats file.  Can't do this sooner since
3442738Sstever@eecs.umich.edu    // the stat file name is set via a .ini param... thus it just got
3452738Sstever@eecs.umich.edu    // opened above during ParamContext::checkAllContexts().
3462738Sstever@eecs.umich.edu
3472738Sstever@eecs.umich.edu    // Print hello message to stats file if it's actually a file.  If
3482738Sstever@eecs.umich.edu    // it's not (i.e. it's cout or cerr) then we already did it above.
3492738Sstever@eecs.umich.edu    if (statStreamIsFile)
3502738Sstever@eecs.umich.edu        sayHello(*statStream);
3512738Sstever@eecs.umich.edu
3522738Sstever@eecs.umich.edu    // Echo command line and all parameter settings to stats file as well.
3532667Sstever@eecs.umich.edu    echoCommandLine(argc, argv, *statStream);
3542738Sstever@eecs.umich.edu    ParamContext::showAllContexts(*statStream);
3552667Sstever@eecs.umich.edu
3562738Sstever@eecs.umich.edu    // Now process the configuration hierarchy and create the SimObjects.
3572655Sstever@eecs.umich.edu    ConfigHierarchy configHierarchy(simConfigDB);
3581388SN/A    configHierarchy.build();
3592SN/A    configHierarchy.createSimObjects();
3602655Sstever@eecs.umich.edu
3612SN/A    // Restore checkpointed state, if any.
3621388SN/A    configHierarchy.unserializeSimObjects();
3631388SN/A
3642738Sstever@eecs.umich.edu    // Done processing the configuration database.
3652SN/A    // Check for unreferenced entries.
3661310SN/A    if (simConfigDB.printUnreferenced() && quitOnUnreferenced) {
3672738Sstever@eecs.umich.edu        cerr << "Fatal: unreferenced .ini sections/entries." << endl
3682738Sstever@eecs.umich.edu             << "If this is not an error, add 'unref_section_ok=y' or "
3692738Sstever@eecs.umich.edu             << "'unref_entries_ok=y' to the appropriate sections "
3702738Sstever@eecs.umich.edu             << "to suppress this message." << endl;
3712738Sstever@eecs.umich.edu        exit(1);
3722738Sstever@eecs.umich.edu    }
3732738Sstever@eecs.umich.edu
3742738Sstever@eecs.umich.edu    SimObject::regAllStats();
3752738Sstever@eecs.umich.edu
3762738Sstever@eecs.umich.edu    // uncomment the following to get PC-based execution-time profile
3772738Sstever@eecs.umich.edu#ifdef DO_PROFILE
3782738Sstever@eecs.umich.edu    init_profile((char *)&_init, (char *)&_fini);
3792738Sstever@eecs.umich.edu#endif
3802738Sstever@eecs.umich.edu
3812738Sstever@eecs.umich.edu    // Check to make sure that the stats package is properly initialized
3822738Sstever@eecs.umich.edu    Statistics::check();
3832738Sstever@eecs.umich.edu
3842738Sstever@eecs.umich.edu    // Nothing to simulate if we don't have at least one CPU somewhere.
3852738Sstever@eecs.umich.edu    if (BaseCPU::numSimulatedCPUs() == 0) {
3862738Sstever@eecs.umich.edu        cerr << "Fatal: no CPUs to simulate." << endl;
3872738Sstever@eecs.umich.edu        exit(1);
3882738Sstever@eecs.umich.edu    }
3892738Sstever@eecs.umich.edu
3902738Sstever@eecs.umich.edu    while (!mainEventQueue.empty()) {
3912738Sstever@eecs.umich.edu        assert(curTick <= mainEventQueue.nextTick() &&
3922738Sstever@eecs.umich.edu               "event scheduled in the past");
3932738Sstever@eecs.umich.edu
3942738Sstever@eecs.umich.edu        // forward current cycle to the time of the first event on the
3952738Sstever@eecs.umich.edu        // queue
3962738Sstever@eecs.umich.edu        curTick = mainEventQueue.nextTick();
3972738Sstever@eecs.umich.edu        mainEventQueue.serviceOne();
3982738Sstever@eecs.umich.edu
3992738Sstever@eecs.umich.edu        if (async_event) {
4002738Sstever@eecs.umich.edu            async_event = false;
4012738Sstever@eecs.umich.edu            if (async_dump) {
4022738Sstever@eecs.umich.edu                async_dump = false;
4032738Sstever@eecs.umich.edu
4042738Sstever@eecs.umich.edu                using namespace Statistics;
4052738Sstever@eecs.umich.edu                SetupEvent(Dump, curTick);
4062738Sstever@eecs.umich.edu            }
4072738Sstever@eecs.umich.edu
4082738Sstever@eecs.umich.edu            if (async_exit) {
4092738Sstever@eecs.umich.edu                async_exit = false;
4102738Sstever@eecs.umich.edu                new SimExitEvent("User requested STOP");
4112738Sstever@eecs.umich.edu            }
4122738Sstever@eecs.umich.edu
4132738Sstever@eecs.umich.edu            if (async_io || async_alarm) {
4141388SN/A                async_io = false;
4151388SN/A                async_alarm = false;
4161388SN/A                pollQueue.service();
4171388SN/A            }
4182667Sstever@eecs.umich.edu        }
4191104SN/A    }
4202SN/A
4211127SN/A    // This should never happen... every conceivable way for the
4221127SN/A    // simulation to terminate (hit max cycles/insts, signal,
4231127SN/A    // simulated system halts/exits) generates an exit event, so we
4242SN/A    // should never run out of events on the queue.
4252738Sstever@eecs.umich.edu    exitNow("improperly exited event loop!", 1);
4262SN/A
4272738Sstever@eecs.umich.edu    return 0;
4282SN/A}
4292SN/A