init.cc (7674:8e3734851770) init.cc (7823:dac01f14f20f)
1/*
2 * Copyright (c) 2000-2005 The Regents of The University of Michigan
3 * Copyright (c) 2008 The Hewlett-Packard Development Company
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Authors: Nathan Binkert
30 */
31
32#include <Python.h>
33#include <marshal.h>
34#include <signal.h>
35
36#include <list>
37#include <iostream>
38#include <string>
39#include <zlib.h>
40
41#include "base/cprintf.hh"
42#include "base/misc.hh"
43#include "base/types.hh"
44#include "sim/async.hh"
45#include "sim/core.hh"
46#include "sim/init.hh"
47
48using namespace std;
49
50/// Stats signal handler.
51void
52dumpStatsHandler(int sigtype)
53{
54 async_event = true;
55 async_statdump = true;
56}
57
58void
59dumprstStatsHandler(int sigtype)
60{
61 async_event = true;
62 async_statdump = true;
63 async_statreset = true;
64}
65
66/// Exit signal handler.
67void
68exitNowHandler(int sigtype)
69{
70 async_event = true;
71 async_exit = true;
72}
73
74/// Abort signal handler.
75void
76abortHandler(int sigtype)
77{
1/*
2 * Copyright (c) 2000-2005 The Regents of The University of Michigan
3 * Copyright (c) 2008 The Hewlett-Packard Development Company
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Authors: Nathan Binkert
30 */
31
32#include <Python.h>
33#include <marshal.h>
34#include <signal.h>
35
36#include <list>
37#include <iostream>
38#include <string>
39#include <zlib.h>
40
41#include "base/cprintf.hh"
42#include "base/misc.hh"
43#include "base/types.hh"
44#include "sim/async.hh"
45#include "sim/core.hh"
46#include "sim/init.hh"
47
48using namespace std;
49
50/// Stats signal handler.
51void
52dumpStatsHandler(int sigtype)
53{
54 async_event = true;
55 async_statdump = true;
56}
57
58void
59dumprstStatsHandler(int sigtype)
60{
61 async_event = true;
62 async_statdump = true;
63 async_statreset = true;
64}
65
66/// Exit signal handler.
67void
68exitNowHandler(int sigtype)
69{
70 async_event = true;
71 async_exit = true;
72}
73
74/// Abort signal handler.
75void
76abortHandler(int sigtype)
77{
78 ccprintf(cerr, "Program aborted at cycle %d\n", curTick);
78 ccprintf(cerr, "Program aborted at cycle %d\n", curTick());
79}
80
81/*
82 * M5 can do several special things when various signals are sent.
83 * None are mandatory.
84 */
85void
86initSignals()
87{
88 // Floating point exceptions may happen on misspeculated paths, so
89 // ignore them
90 signal(SIGFPE, SIG_IGN);
91
92 // We use SIGTRAP sometimes for debugging
93 signal(SIGTRAP, SIG_IGN);
94
95 // Dump intermediate stats
96 signal(SIGUSR1, dumpStatsHandler);
97
98 // Dump intermediate stats and reset them
99 signal(SIGUSR2, dumprstStatsHandler);
100
101 // Exit cleanly on Interrupt (Ctrl-C)
102 signal(SIGINT, exitNowHandler);
103
104 // Print out cycle number on abort
105 signal(SIGABRT, abortHandler);
106}
107
108// The python library is totally messed up with respect to constness,
109// so make a simple macro to make life a little easier
110#define PyCC(x) (const_cast<char *>(x))
111
112EmbeddedPython *EmbeddedPython::importer = NULL;
113PyObject *EmbeddedPython::importerModule = NULL;
114EmbeddedPython::EmbeddedPython(const char *filename, const char *abspath,
115 const char *modpath, const char *code, int zlen, int len)
116 : filename(filename), abspath(abspath), modpath(modpath), code(code),
117 zlen(zlen), len(len)
118{
119 // if we've added the importer keep track of it because we need it
120 // to bootstrap.
121 if (string(modpath) == string("importer"))
122 importer = this;
123 else
124 getList().push_back(this);
125}
126
127list<EmbeddedPython *> &
128EmbeddedPython::getList()
129{
130 static list<EmbeddedPython *> the_list;
131 return the_list;
132}
133
134/*
135 * Uncompress and unmarshal the code object stored in the
136 * EmbeddedPython
137 */
138PyObject *
139EmbeddedPython::getCode() const
140{
141 Bytef marshalled[len];
142 uLongf unzlen = len;
143 int ret = uncompress(marshalled, &unzlen, (const Bytef *)code, zlen);
144 if (ret != Z_OK)
145 panic("Could not uncompress code: %s\n", zError(ret));
146 assert(unzlen == (uLongf)len);
147
148 return PyMarshal_ReadObjectFromString((char *)marshalled, len);
149}
150
151bool
152EmbeddedPython::addModule() const
153{
154 PyObject *code = getCode();
155 PyObject *result = PyObject_CallMethod(importerModule, PyCC("add_module"),
156 PyCC("sssO"), filename, abspath, modpath, code);
157 if (!result) {
158 PyErr_Print();
159 return false;
160 }
161
162 Py_DECREF(result);
163 return true;
164}
165
166/*
167 * Load and initialize all of the python parts of M5, including Swig
168 * and the embedded module importer.
169 */
170int
171EmbeddedPython::initAll()
172{
173 // Load the importer module
174 PyObject *code = importer->getCode();
175 importerModule = PyImport_ExecCodeModule(PyCC("importer"), code);
176 if (!importerModule) {
177 PyErr_Print();
178 return 1;
179 }
180
181 // Load the rest of the embedded python files into the embedded
182 // python importer
183 list<EmbeddedPython *>::iterator i = getList().begin();
184 list<EmbeddedPython *>::iterator end = getList().end();
185 for (; i != end; ++i)
186 if (!(*i)->addModule())
187 return 1;
188
189 return 0;
190}
191
192EmbeddedSwig::EmbeddedSwig(void (*init_func)())
193 : initFunc(init_func)
194{
195 getList().push_back(this);
196}
197
198list<EmbeddedSwig *> &
199EmbeddedSwig::getList()
200{
201 static list<EmbeddedSwig *> the_list;
202 return the_list;
203}
204
205void
206EmbeddedSwig::initAll()
207{
208 // initialize SWIG modules. initSwig() is autogenerated and calls
209 // all of the individual swig initialization functions.
210 list<EmbeddedSwig *>::iterator i = getList().begin();
211 list<EmbeddedSwig *>::iterator end = getList().end();
212 for (; i != end; ++i)
213 (*i)->initFunc();
214}
215
216int
217initM5Python()
218{
219 EmbeddedSwig::initAll();
220 return EmbeddedPython::initAll();
221}
222
223/*
224 * Start up the M5 simulator. This mostly vectors into the python
225 * main function.
226 */
227int
228m5Main(int argc, char **argv)
229{
230 PySys_SetArgv(argc, argv);
231
232 // We have to set things up in the special __main__ module
233 PyObject *module = PyImport_AddModule(PyCC("__main__"));
234 if (module == NULL)
235 panic("Could not import __main__");
236 PyObject *dict = PyModule_GetDict(module);
237
238 // import the main m5 module
239 PyObject *result;
240 result = PyRun_String("import m5", Py_file_input, dict, dict);
241 if (!result) {
242 PyErr_Print();
243 return 1;
244 }
245 Py_DECREF(result);
246
247 // Start m5
248 result = PyRun_String("m5.main()", Py_file_input, dict, dict);
249 if (!result) {
250 PyErr_Print();
251 return 1;
252 }
253 Py_DECREF(result);
254
255 return 0;
256}
257
258PyMODINIT_FUNC
259initm5(void)
260{
261 initM5Python();
262 PyImport_ImportModule(PyCC("m5"));
263}
79}
80
81/*
82 * M5 can do several special things when various signals are sent.
83 * None are mandatory.
84 */
85void
86initSignals()
87{
88 // Floating point exceptions may happen on misspeculated paths, so
89 // ignore them
90 signal(SIGFPE, SIG_IGN);
91
92 // We use SIGTRAP sometimes for debugging
93 signal(SIGTRAP, SIG_IGN);
94
95 // Dump intermediate stats
96 signal(SIGUSR1, dumpStatsHandler);
97
98 // Dump intermediate stats and reset them
99 signal(SIGUSR2, dumprstStatsHandler);
100
101 // Exit cleanly on Interrupt (Ctrl-C)
102 signal(SIGINT, exitNowHandler);
103
104 // Print out cycle number on abort
105 signal(SIGABRT, abortHandler);
106}
107
108// The python library is totally messed up with respect to constness,
109// so make a simple macro to make life a little easier
110#define PyCC(x) (const_cast<char *>(x))
111
112EmbeddedPython *EmbeddedPython::importer = NULL;
113PyObject *EmbeddedPython::importerModule = NULL;
114EmbeddedPython::EmbeddedPython(const char *filename, const char *abspath,
115 const char *modpath, const char *code, int zlen, int len)
116 : filename(filename), abspath(abspath), modpath(modpath), code(code),
117 zlen(zlen), len(len)
118{
119 // if we've added the importer keep track of it because we need it
120 // to bootstrap.
121 if (string(modpath) == string("importer"))
122 importer = this;
123 else
124 getList().push_back(this);
125}
126
127list<EmbeddedPython *> &
128EmbeddedPython::getList()
129{
130 static list<EmbeddedPython *> the_list;
131 return the_list;
132}
133
134/*
135 * Uncompress and unmarshal the code object stored in the
136 * EmbeddedPython
137 */
138PyObject *
139EmbeddedPython::getCode() const
140{
141 Bytef marshalled[len];
142 uLongf unzlen = len;
143 int ret = uncompress(marshalled, &unzlen, (const Bytef *)code, zlen);
144 if (ret != Z_OK)
145 panic("Could not uncompress code: %s\n", zError(ret));
146 assert(unzlen == (uLongf)len);
147
148 return PyMarshal_ReadObjectFromString((char *)marshalled, len);
149}
150
151bool
152EmbeddedPython::addModule() const
153{
154 PyObject *code = getCode();
155 PyObject *result = PyObject_CallMethod(importerModule, PyCC("add_module"),
156 PyCC("sssO"), filename, abspath, modpath, code);
157 if (!result) {
158 PyErr_Print();
159 return false;
160 }
161
162 Py_DECREF(result);
163 return true;
164}
165
166/*
167 * Load and initialize all of the python parts of M5, including Swig
168 * and the embedded module importer.
169 */
170int
171EmbeddedPython::initAll()
172{
173 // Load the importer module
174 PyObject *code = importer->getCode();
175 importerModule = PyImport_ExecCodeModule(PyCC("importer"), code);
176 if (!importerModule) {
177 PyErr_Print();
178 return 1;
179 }
180
181 // Load the rest of the embedded python files into the embedded
182 // python importer
183 list<EmbeddedPython *>::iterator i = getList().begin();
184 list<EmbeddedPython *>::iterator end = getList().end();
185 for (; i != end; ++i)
186 if (!(*i)->addModule())
187 return 1;
188
189 return 0;
190}
191
192EmbeddedSwig::EmbeddedSwig(void (*init_func)())
193 : initFunc(init_func)
194{
195 getList().push_back(this);
196}
197
198list<EmbeddedSwig *> &
199EmbeddedSwig::getList()
200{
201 static list<EmbeddedSwig *> the_list;
202 return the_list;
203}
204
205void
206EmbeddedSwig::initAll()
207{
208 // initialize SWIG modules. initSwig() is autogenerated and calls
209 // all of the individual swig initialization functions.
210 list<EmbeddedSwig *>::iterator i = getList().begin();
211 list<EmbeddedSwig *>::iterator end = getList().end();
212 for (; i != end; ++i)
213 (*i)->initFunc();
214}
215
216int
217initM5Python()
218{
219 EmbeddedSwig::initAll();
220 return EmbeddedPython::initAll();
221}
222
223/*
224 * Start up the M5 simulator. This mostly vectors into the python
225 * main function.
226 */
227int
228m5Main(int argc, char **argv)
229{
230 PySys_SetArgv(argc, argv);
231
232 // We have to set things up in the special __main__ module
233 PyObject *module = PyImport_AddModule(PyCC("__main__"));
234 if (module == NULL)
235 panic("Could not import __main__");
236 PyObject *dict = PyModule_GetDict(module);
237
238 // import the main m5 module
239 PyObject *result;
240 result = PyRun_String("import m5", Py_file_input, dict, dict);
241 if (!result) {
242 PyErr_Print();
243 return 1;
244 }
245 Py_DECREF(result);
246
247 // Start m5
248 result = PyRun_String("m5.main()", Py_file_input, dict, dict);
249 if (!result) {
250 PyErr_Print();
251 return 1;
252 }
253 Py_DECREF(result);
254
255 return 0;
256}
257
258PyMODINIT_FUNC
259initm5(void)
260{
261 initM5Python();
262 PyImport_ImportModule(PyCC("m5"));
263}