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