Instead of keeping track of the fraction of time that we're
[gem5.git] / sim / sim_events.cc
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
38 using namespace std;
39
40 //
41 // handle termination event
42 //
43 void
44 SimExitEvent::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
60 const char *
61 SimExitEvent::description()
62 {
63 return "simulation termination";
64 }
65
66 //
67 // constructor: automatically schedules at specified time
68 //
69 CountedExitEvent::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 //
85 void
86 CountedExitEvent::process()
87 {
88 if (--downCounter == 0) {
89 new SimExitEvent(cause, 1);
90 }
91 }
92
93
94 const char *
95 CountedExitEvent::description()
96 {
97 return "counted exit";
98 }
99
100 #ifdef CHECK_SWAP_CYCLES
101 new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
102 #endif
103
104 void
105 CheckSwapEvent::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
124 const char *
125 CheckSwapEvent::description()
126 {
127 return "check swap";
128 }
129
130
131 ///////////////////////////////////////////////////
132 //
133 // Simulation termination parameters
134 //
135 ///////////////////////////////////////////////////
136
137 class TermParamContext : public ParamContext
138 {
139 public:
140 TermParamContext(const string &_iniSection)
141 : ParamContext(_iniSection) {}
142 void checkParams();
143 };
144
145 TermParamContext simTerminationParams("max");
146
147 Param<Tick> max_cycle(&simTerminationParams, "cycle",
148 "maximum number of cycles to execute");
149
150 void
151 TermParamContext::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 //
163 class 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 //
178 ProgressEvent::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 //
187 void
188 ProgressEvent::process()
189 {
190 DPRINTFN("ProgressEvent\n");
191 // reschedule for next interval
192 schedule(curTick + interval);
193 }
194
195
196 const char *
197 ProgressEvent::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.
211 class ProgressParamContext : public ParamContext
212 {
213 public:
214 ProgressParamContext(const string &_iniSection)
215 : ParamContext(_iniSection) {}
216 void checkParams();
217 };
218
219 ProgressParamContext progessMessageParams("progress");
220
221 Param<Tick> progress_interval(&progessMessageParams, "cycle",
222 "cycle interval for progress messages");
223
224 /* check execute options */
225 void
226 ProgressParamContext::checkParams()
227 {
228 if (progress_interval.isValid())
229 new ProgressEvent(&mainEventQueue, progress_interval);
230 }