sim_events.cc revision 85
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//
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