simobject.py
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· Python 代码 · 共 911 行 · 第 1/3 页
PY
911 行
# no valid assignment... raise exception raise AttributeError, "Class %s has no parameter %s" \ % (self.__class__.__name__, attr) # this hack allows tacking a '[0]' onto parameters that may or may # not be vectors, and always getting the first element (e.g. cpus) def __getitem__(self, key): if key == 0: return self raise TypeError, "Non-zero index '%s' to SimObject" % key # clear out children with given name, even if it's a vector def clear_child(self, name): if not self._children.has_key(name): return child = self._children[name] if isinstance(child, SimObjVector): for i in xrange(len(child)): del self._children["s%d" % (name, i)] del self._children[name] def add_child(self, name, value): self._children[name] = value def _maybe_set_parent(self, parent, name): if not self._parent: self._parent = parent self._name = name parent.add_child(name, self) def _set_child(self, attr, value): # if RHS is a SimObject, it's an implicit child assignment # clear out old child with this name, if any self.clear_child(attr) if isSimObject(value): value._maybe_set_parent(self, attr) elif isSimObjectSequence(value): value = SimObjVector(value) if len(value) == 1: value[0]._maybe_set_parent(self, attr) else: for i,v in enumerate(value): v._maybe_set_parent(self, "%s%d" % (attr, i)) self._values[attr] = value def path(self): if not self._parent: return 'root' ppath = self._parent.path() if ppath == 'root': return self._name return ppath + "." + self._name def __str__(self): return self.path() def ini_str(self): return self.path() def find_any(self, ptype): if isinstance(self, ptype): return self, True found_obj = None for child in self._children.itervalues(): if isinstance(child, ptype): if found_obj != None and child != found_obj: raise AttributeError, \ 'parent.any matched more than one: %s %s' % \ (found_obj.path, child.path) found_obj = child # search param space for pname,pdesc in self._params.iteritems(): if issubclass(pdesc.ptype, ptype): match_obj = self._values[pname] if found_obj != None and found_obj != match_obj: raise AttributeError, \ 'parent.any matched more than one: %s' % obj.path found_obj = match_obj return found_obj, found_obj != None def unproxy(self, base): return self def unproxy_all(self): for param in self._params.iterkeys(): value = self._values.get(param) if value != None and proxy.isproxy(value): try: value = value.unproxy(self) except: print "Error in unproxying param '%s' of %s" % \ (param, self.path()) raise setattr(self, param, value) # Unproxy ports in sorted order so that 'append' operations on # vector ports are done in a deterministic fashion. port_names = self._ports.keys() port_names.sort() for port_name in port_names: port = self._port_refs.get(port_name) if port != None: port.unproxy(self) # Unproxy children in sorted order for determinism also. child_names = self._children.keys() child_names.sort() for child in child_names: self._children[child].unproxy_all() def print_ini(self, ini_file): print >>ini_file, '[' + self.path() + ']' # .ini section header instanceDict[self.path()] = self if hasattr(self, 'type'): print >>ini_file, 'type=%s' % self.type child_names = self._children.keys() child_names.sort() if len(child_names): print >>ini_file, 'children=%s' % ' '.join(child_names) param_names = self._params.keys() param_names.sort() for param in param_names: value = self._values.get(param) if value != None: print >>ini_file, '%s=%s' % (param, self._values[param].ini_str()) port_names = self._ports.keys() port_names.sort() for port_name in port_names: port = self._port_refs.get(port_name, None) if port != None: print >>ini_file, '%s=%s' % (port_name, port.ini_str()) print >>ini_file # blank line between objects for child in child_names: self._children[child].print_ini(ini_file) def getCCParams(self): if self._ccParams: return self._ccParams cc_params_struct = getattr(m5.objects.params, '%sParams' % self.type) cc_params = cc_params_struct() cc_params.object = self cc_params.name = str(self) param_names = self._params.keys() param_names.sort() for param in param_names: value = self._values.get(param) if value is None: continue value = value.getValue() if isinstance(self._params[param], VectorParamDesc): assert isinstance(value, list) vec = getattr(cc_params, param) assert not len(vec) for v in value: vec.append(v) else: setattr(cc_params, param, value) port_names = self._ports.keys() port_names.sort() for port_name in port_names: port = self._port_refs.get(port_name, None) if port != None: setattr(cc_params, port_name, port) self._ccParams = cc_params return self._ccParams # Get C++ object corresponding to this object, calling C++ if # necessary to construct it. Does *not* recursively create # children. def getCCObject(self): if not self._ccObject: # Cycles in the configuration heirarchy are not supported. This # will catch the resulting recursion and stop. self._ccObject = -1 params = self.getCCParams() self._ccObject = params.create() elif self._ccObject == -1: raise RuntimeError, "%s: Cycle found in configuration heirarchy." \ % self.path() return self._ccObject # Call C++ to create C++ object corresponding to this object and # (recursively) all its children def createCCObject(self): self.getCCParams() self.getCCObject() # force creation for child in self._children.itervalues(): child.createCCObject() def getValue(self): return self.getCCObject() # Create C++ port connections corresponding to the connections in # _port_refs (& recursively for all children) def connectPorts(self): for portRef in self._port_refs.itervalues(): portRef.ccConnect() for child in self._children.itervalues(): child.connectPorts() def startDrain(self, drain_event, recursive): count = 0 if isinstance(self, SimObject): count += self._ccObject.drain(drain_event) if recursive: for child in self._children.itervalues(): count += child.startDrain(drain_event, True) return count def resume(self): if isinstance(self, SimObject): self._ccObject.resume() for child in self._children.itervalues(): child.resume() def getMemoryMode(self): if not isinstance(self, m5.objects.System): return None return self._ccObject.getMemoryMode() def changeTiming(self, mode): if isinstance(self, m5.objects.System): # i don't know if there's a better way to do this - calling # setMemoryMode directly from self._ccObject results in calling # SimObject::setMemoryMode, not the System::setMemoryMode self._ccObject.setMemoryMode(mode) for child in self._children.itervalues(): child.changeTiming(mode) def takeOverFrom(self, old_cpu): self._ccObject.takeOverFrom(old_cpu._ccObject) # generate output file for 'dot' to display as a pretty graph. # this code is currently broken. def outputDot(self, dot): label = "{%s|" % self.path if isSimObject(self.realtype): label += '%s|' % self.type if self.children: # instantiate children in same order they were added for # backward compatibility (else we can end up with cpu1 # before cpu0). for c in self.children: dot.add_edge(pydot.Edge(self.path,c.path, style="bold")) simobjs = [] for param in self.params: try: if param.value is None: raise AttributeError, 'Parameter with no value' value = param.value string = param.string(value) except Exception, e: msg = 'exception in %s:%s\n%s' % (self.name, param.name, e) e.args = (msg, ) raise if isSimObject(param.ptype) and string != "Null": simobjs.append(string) else: label += '%s = %s\\n' % (param.name, string) for so in simobjs: label += "|<%s> %s" % (so, so) dot.add_edge(pydot.Edge("%s:%s" % (self.path, so), so, tailport="w")) label += '}' dot.add_node(pydot.Node(self.path,shape="Mrecord",label=label)) # recursively dump out children for c in self.children: c.outputDot(dot)# Function to provide to C++ so it can look up instances based on pathsdef resolveSimObject(name): obj = instanceDict[name] return obj.getCCObject()# __all__ defines the list of symbols that get exported when# 'from config import *' is invoked. Try to keep this reasonably# short to avoid polluting other namespaces.__all__ = [ 'SimObject' ]
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?