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