sim_object.cc revision 2
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 <assert.h>
30
31#include "sim_object.hh"
32#include "inifile.hh"
33#include "configfile.hh"
34#include "host.hh"
35#include "misc.hh"
36#include "trace.hh"
37#include "sim_stats.hh"
38#include "stats.hh"
39
40using namespace std;
41
42
43////////////////////////////////////////////////////////////////////////
44//
45// SimObject member definitions
46//
47////////////////////////////////////////////////////////////////////////
48
49//
50// static list of all SimObjects, used for initialization etc.
51//
52SimObject::SimObjectList SimObject::simObjectList;
53
54//
55// SimObject constructor: used to maintain static simObjectList
56//
57SimObject::SimObject(const string &_name)
58    : Serializeable(_name)
59{
60    simObjectList.push_back(this);
61}
62
63//
64// no default statistics, so nothing to do in base implementation
65//
66void
67SimObject::reg_stats(struct stat_sdb_t *sdb)
68{
69}
70
71void
72SimObject::regStats()
73{
74}
75
76void
77SimObject::regFormulas()
78{
79}
80
81//
82// no default extra output
83//
84void
85SimObject::printExtraOutput(ostream &os)
86{
87}
88
89//
90// static function: call reg_stats() on all SimObjects.
91//
92void
93SimObject::regAllStats()
94{
95    SimObjectList::iterator i;
96    SimObjectList::iterator end = simObjectList.end();
97
98    /**
99     * @todo change cprintfs to DPRINTFs
100     */
101    for (i = simObjectList.begin(); i != end; ++i) {
102#ifdef STAT_DEBUG
103        cprintf("registering stats for %s\n", (*i)->name());
104#endif
105        (*i)->reg_stats(sim_sdb);
106        (*i)->regStats();
107    }
108
109    for (i = simObjectList.begin(); i != end; ++i) {
110#ifdef STAT_DEBUG
111        cprintf("registering formulas for %s\n", (*i)->name());
112#endif
113        (*i)->regFormulas();
114   }
115}
116
117//
118// static function: call printExtraOutput() on all SimObjects.
119//
120void
121SimObject::printAllExtraOutput(ostream &os)
122{
123    SimObjectList::iterator i;
124
125    for (i = simObjectList.begin(); i != simObjectList.end(); ++i) {
126        (*i)->printExtraOutput(os);
127   }
128}
129
130///////////////////////////////////////////
131//
132// SimObjectBuilder member definitions
133//
134///////////////////////////////////////////
135
136// override ParamContext::parseParams() to check params based on
137// instance name first.  If not found, then check based on iniSection
138// (as in default ParamContext implementation).
139void
140SimObjectBuilder::parseParams(IniFile &iniFile)
141{
142    iniFilePtr = &iniFile;	// set object member
143
144    ParamList::iterator i;
145
146    for (i = paramList->begin(); i != paramList->end(); ++i) {
147        string string_value;
148
149        if (iniFile.findDefault(instanceName, (*i)->name, string_value)) {
150            (*i)->parse(string_value);
151        }
152        else if (iniFile.findDefault(iniSection, (*i)->name, string_value)) {
153            (*i)->parse(string_value);
154        }
155    }
156}
157
158
159void
160SimObjectBuilder::printErrorProlog(ostream &os)
161{
162    os << "Error creating object '" << getInstanceName()
163       << "' of type '" << simObjClassName
164       << "', section '" << iniSection << "':" << endl;
165}
166
167
168////////////////////////////////////////////////////////////////////////
169//
170// SimObjectClass member definitions
171//
172////////////////////////////////////////////////////////////////////////
173
174// Map of class names to SimObjectBuilder creation functions.  Need to
175// make this a pointer so we can force initialization on the first
176// reference; otherwise, some SimObjectClass constructors may be invoked
177// before the classMap constructor.
178map<string,SimObjectClass::CreateFunc> *SimObjectClass::classMap = NULL;
179
180// SimObjectClass constructor: add mapping to classMap
181SimObjectClass::SimObjectClass(const string &className, CreateFunc createFunc)
182{
183    if (classMap == NULL)
184        classMap = new map<string,SimObjectClass::CreateFunc>();
185
186    if ((*classMap)[className])
187    {
188        cerr << "Error: simulation object class " << className << " redefined"
189             << endl;
190        fatal("");
191    }
192
193    // add className --> createFunc to class map
194    (*classMap)[className] = createFunc;
195}
196
197
198//
199//
200SimObject *
201SimObjectClass::createObject(IniFile &configDB,
202                             const string &configClassName,
203                             const string &objName,
204                             ConfigNode *configNode)
205{
206    // find simulation object class name from configuration class
207    // (specified by 'type=' parameter)
208    string simObjClassName;
209
210    if (!configDB.findDefault(configClassName, "type", simObjClassName)) {
211        cerr << "Configuration class '" << configClassName << "' not found."
212             << endl;
213        abort();
214    }
215
216    // look up className to get appropriate createFunc
217    if (classMap->find(simObjClassName) == classMap->end()) {
218        cerr << "Simulator object class '" << simObjClassName << "' not found."
219             << endl;
220        abort();
221    }
222
223    CreateFunc createFunc = (*classMap)[simObjClassName];
224
225    // call createFunc with config hierarchy node to get object
226    // builder instance (context with parameters for object creation)
227    SimObjectBuilder *objectBuilder = (*createFunc)(configClassName,
228                                                    objName, configNode,
229                                                    simObjClassName);
230
231    assert(objectBuilder != NULL);
232
233    // parse all parameters in context to generate parameter values
234    objectBuilder->parseParams(configDB);
235
236    // now create the actual simulation object
237    SimObject *object = objectBuilder->create();
238
239    assert(object != NULL);
240
241    // echo object parameters to stats file (for documenting the
242    // config used to generate the associated stats)
243    *statStream << "[" << object->name() << "]" << endl;
244    *statStream << "type=" << simObjClassName << endl;
245    objectBuilder->showParams(*statStream);
246    *statStream << endl;
247
248    // done with the SimObjectBuilder now
249    delete objectBuilder;
250
251    return object;
252}
253
254
255//
256// static method:
257//
258void
259SimObjectClass::describeAllClasses(ostream &os)
260{
261    map<string,CreateFunc>::iterator iter;
262
263    for (iter = classMap->begin(); iter != classMap->end(); ++iter) {
264        const string &className = iter->first;
265        CreateFunc createFunc = iter->second;
266
267        os << "[" << className << "]\n";
268
269        // create dummy object builder just to instantiate parameters
270        SimObjectBuilder *objectBuilder = (*createFunc)("", "", NULL, "");
271
272        // now get the object builder to describe ite params
273        objectBuilder->describeParams(os);
274
275        os << endl;
276
277        // done with the object builder now
278        delete objectBuilder;
279    }
280}
281