Source code for mcgdb.model.task.environment.p2012.pedf.representation

import gdb

import mcgdb
from mcgdb.toolbox.target import my_archi
from mcgdb.toolbox import my_gdb
from mcgdb.model.task import representation

#############################################

@my_gdb.Listed
@my_gdb.Numbered
@my_gdb.Dicted
[docs]class Filter(representation.CommComponent): def __init__(self, name, instance, type_=None): representation.CommComponent.__init__(self) Filter.init_dict(str(instance), self) if type_ is not None: if type_.endswith("Base"): type_ = type_[:type_.rindex("Base")] type_ = type_.replace("_", ".") self.type = type_ if name is None: if "Filter." in self.type: splitIdx = self.type.index("Filter.") elif "Module." in self.type: splitIdx = self.type.index("Module.") else: splitIdx = len(self.type) name = self.type[0:splitIdx] self.name = str(name) self.instance = instance.cast(instance.dynamic_type) self.owner_itf = None self.is_top = False self.running = False self.executing = False self.state = "Never executed" #self.thread = None self.work_count = 0 self.messages = [] #work_func = "%sFilter_work_function" % self.name #changed that for distnace: work_func = "%sFilter_work_function" % self.name.replace(".PedfBaseClass", "").replace(".", "_") work_func = work_func self.work_breakpoint = None self.work_method = None #if "Red" in self.name or "Hwcfg" in self.name: #work_func = "toto" pending = "pending" in gdb.execute("break '%s'" % work_func, to_string=True) gdb.breakpoints()[-1].delete() #pending = gdb.lookup_symbol(work_func)[0] is None; if not pending: import handle_workMeth try: self.work_breakpoint = handle_workMeth.WorkMethBreakpoint(work_func) except my_gdb.AlreadyInstalledException as e: self.work_breakpoint = e.actual self.work_method = work_func else: print ("nop", work_func) def __str__(self): return "%s" % self.name
[docs] def set_name(self, name): self.name = name
[docs] def consume_message(self, message): self.messages.append(message)
[docs] def produce_message(self, itf): return None
[docs] def get_messages(self): return self.messages
[docs] def get_mark(self): try: current = gdb.parse_and_eval("_mind_this->__component_internal_data->pedf_ctlPtr") if current == self.instance: return "*" except gdb.error: pass return " "
[docs] def run(self): #my_gdb.push_stop_request("%s --> %s" % (self.name, self.state)) #gdb.execute("where") #return self.state = "Running" #self.thread = gdb.parse_and_eval("&runTime.getThread()") self.running = True self.executing = True self.work_count += 1 self.state_changed()
[docs] def finish_run(self): self.state = "Not running" self.running = False self.executing = False self.state_changed()
[docs] def state_changed(self, itf=None): #print ("%s --> %s" % (self.name, self.state)) #gdb.execute("graph-it +suffix=", to_string=True) return #gdb.execute("!eog /tmp/my_graph.png") #gdb.execute("!sleep 1") my_gdb.push_stop_request("%s --> %s" % (self.name, self.state)) pass
@my_gdb.Listed @my_gdb.Numbered @my_gdb.Dicted
[docs]class Module(Filter): def __init__(self, name, instance, type_=None): Filter.__init__(self, name, instance, type_) Module.init_dict(str(instance), self) self.controller_itf = None
[docs] def set_name(self, name): self.name = name if self.controller_itf is not None: self.controller_itf.comm_entity.set_name(name)
@my_gdb.Listed @my_gdb.Numbered @my_gdb.Dicted
[docs]class Worker(Filter): def __init__(self, instance, parent): Filter.__init__(self, parent, instance, type_="Controller") Worker.init_dict(str(instance), self) self.owner_itf = None def __str__(self): if self.name is not None: return "%s" % self.name return "Worker"
[docs] def set_name(self, name): self.name = "%s_controller" % name
[docs]class Interface(representation.Endpoint): ITF_TYPE = "Interface" def __init__(self, module, name=None): mcgdb.representation.Endpoint.__init__(self, module) self.name = name self.busy = None self.blocking = False def __str__(self): if self.name is None: return self.__class__.ITF_TYPE else: return "%s (%s)" % (self.name, self.__class__.ITF_TYPE)
[docs] def get_other_side(self): if self.link is None: return None if len(self.link.endpoints) == 1: raise ValueError("Link '%s' has only 1 endpoint." % self.link) if len(self.link.endpoints) != 2: raise ValueError("Link '%s' has more than 2 endpoints." % self.link) for ep in self.link.endpoints: if ep is not self: return ep
[docs] def fetch_data(self): self.comm_entity.state = "fetching data (%s)" % self.name self.busy = self self.link.count -= 1 self.link.out_count += 1 self.comm_entity.state_changed(itf=self)
[docs] def finish_fetch_data(self): self.comm_entity.state = "Running" self.busy = None self.comm_entity.state_changed(itf=self)
[docs] def pop_data(self): self.comm_entity.state = "Blocked poping (%s)" % self.name self.comm_entity.executing = False self.blocking = True stop_on_deadlock() self.comm_entity.state_changed(itf=self)
[docs] def finish_pop_data(self): self.comm_entity.state = "Running" self.comm_entity.executing = True self.blocking = False self.comm_entity.state_changed(itf=self)
[docs] def push_data(self): self.comm_entity.state = "flushing data (%s)" % self.name self.busy = self self.comm_entity.state_changed(itf=self)
[docs] def finish_push_data(self): self.comm_entity.state = "Running" self.busy = None self.comm_entity.state_changed(itf=self)
[docs] def flush_data(self): self.comm_entity.state = "Blocked flushing (%s)" % self.name self.comm_entity.executing = False self.blocking = True self.busy = self self.link.count += 1 self.link.in_count += 1 self.comm_entity.state_changed(itf=self)
[docs] def finish_flush_data(self): self.comm_entity.state = "Running" self.comm_entity.executing = True self.blocking = False self.busy = None self.comm_entity.state_changed(itf=self)
####
[docs]class OwnerInterface(Interface): ITF_TYPE = "Owner" def __init__(self, module, name=None): Interface.__init__(self, module, name)
[docs]class OwneeInterface(Interface): ITF_TYPE = "Ownee" def __init__(self, module): Interface.__init__(self, module)
####
[docs]class WorkerInterface(OwneeInterface): ITF_TYPE = "Worker" def __init__(self, module): OwneeInterface.__init__(self, module)
[docs]class ControllerInterface(OwnerInterface): ITF_TYPE = "Controller" def __init__(self, module): OwnerInterface.__init__(self, module, name=None)
#### @my_gdb.Listed @my_gdb.Dicted
[docs]class DataStreamInterface(Interface): ITF_TYPE = "DataStream" def __init__(self, instance, module, name, is_source): Interface.__init__(self, module, name) if instance is not None: if instance.type.code == gdb.TYPE_CODE_REF: instance = instance.address if not str(instance.dynamic_type).endswith("*"): instance = instance.address DataStreamInterface.init_dict(str(instance), self) self.bridge = None self.real = None self.instance = instance self.is_source = is_source self.messages = []
[docs] def produce_message(self): return self.do_produce_message()
[docs] def do_produce_message(self): return model.representation.Message("%s/%s" % (self.comm_entity, self.name), None, "DataStream<>")
[docs] def consume_message(self, msg): self.do_consume_message(msg)
[docs] def do_consume_message(self, msg): self.messages.append(msg)
[docs] def get_messages(self): return self.messages
def __str__(self): return " ".join(( self.name, str(self.instance), "NA" if self.instance is None else str(self.instance.type)))
####
[docs]class DataStreamBridgeInterface(DataStreamInterface): ITF_TYPE = "DataStream Bridge" def __init__(self, real): DataStreamInterface.__init__(self, None, real.comm_entity, real.name, real.is_source) self.real = real real.real = self self.is_source = real.is_source
#### @my_gdb.Listed @my_gdb.Dicted
[docs]class DynamicControlInterface(Interface): ITF_TYPE = "DynamicControl" def __init__(self, instance, module, name): Interface.__init__(self, module, name) if instance.type.code == gdb.TYPE_CODE_REF: instance = instance.address str_instance = str(instance) DynamicControlInterface.init_dict(str_instance, self) self.instance = instance self.is_source = "Out" in str(instance.dynamic_type)
[docs] def produce_message(self): return self.do_produce_message()
[docs] def do_produce_message(self): cmd = gdb.parse_and_eval("cmd") return model.representation.Message("%s/%s" % (self.comm_entity, self.name), str(cmd), "DynamicControl<%s>" % cmd.dynamic_type)
#############################################
[docs]def connect_control_interface(parent, worker): link = WorkerLink() def connect(module, is_worker): Interface = WorkerInterface if is_worker else ControllerInterface itf = Interface(module) link.add_endpoint(itf) return itf parent.controller_itf = connect(worker, is_worker=True) worker.owner_itf = connect(parent, is_worker=False) worker.name = "%s_controller" % parent.name
[docs]def connect_owner_interface(parent, son): link = OwnerLink() def connect(module, is_owner): Interface = OwnerInterface if is_owner else OwneeInterface itf = Interface(module) link.add_endpoint(itf) return itf owner_itf = connect(parent, is_owner=True) connect(son, is_owner=False) son.owner_itf = owner_itf
[docs]def connect_datastream_interface(this, this_module, this_name, that, that_module, that_name): link = DataStreamLink() def connect(instance, module, name, is_source=False): itf = DataStreamInterface(instance, module, name, is_source) link.add_endpoint(itf) return itf this_itf = connect(this, this_module, this_name, is_source=True) that_itf = connect(that, that_module, that_name) def getBridgeLinkInterface(local_itf): for other_local_itf in local_itf.comm_entity.endpoints: if not isinstance(other_local_itf, DataStreamInterface): continue if other_local_itf is local_itf: continue if local_itf.name is None or other_local_itf.name is None: continue if local_itf.name != other_local_itf.name: continue #same name, create a bridge #(two interface CANT have the same name within ONE entity) if other_local_itf.real is None: #no bridge endpoint on other_local_itf #cas 1, 3 link = DataStreamBridgeLink(local_itf.link, other_local_itf.link) other_remote_itf = DataStreamBridgeInterface(other_local_itf.get_other_side()) link.add_endpoint(other_remote_itf) local_itf.bridge = other_local_itf other_local_itf.bridge = local_itf else: #this is a bridge endpoint #cas 5, 6 bridge_itf = other_local_itf if not isinstance(bridge_itf, DataStreamBridgeInterface): bridge_itf = bridge_itf.real link = bridge_itf.link bridge_itf.real.real = None bridge_itf.endpoint_closed() return link, local_itf.get_other_side() else: #cas 0 return None, local_itf.get_other_side() link_this, to_connect_that = getBridgeLinkInterface(this_itf) link_that, to_connect_this = getBridgeLinkInterface(that_itf) #cas 1 if link_this is None and link_that is None: pass #cas 1 elif link_this is not None and link_that is None: assert to_connect_that.real is None link_this.add_endpoint(DataStreamBridgeInterface(to_connect_that)) to_connect_that.link.bridge = link_this #cas 2 elif link_that is not None and link_this is None: assert to_connect_this.real is None link_that.add_endpoint(DataStreamBridgeInterface(to_connect_this)) to_connect_this.link.bridge = link_that else: assert link_this is not None and link_that is not None assert len(link_this.endpoints) == 1 assert len(link_that.endpoints) == 1 itf = link_that.endpoints[0] itf.link_destructed() for bridged in link_that.bridges: bridged.bridge = link_this link_this.add_endpoint(itf)
[docs]def connect_dynamic_control_interface(this, this_module, this_name, that, that_module, that_name): link = DynamicControlLink() def connect(instance, module, name): if isinstance(module, Module) and module.controller_itf is not None: module = module.controller_itf.comm_entity itf = DynamicControlInterface(instance, module, name) link.add_endpoint(itf) connect(this, this_module, this_name) connect(that, that_module, that_name)
[docs]def complete_interface_mapping(): import handle_ds_operator handle_ds_operator.init() for module in Filter.list_: module.instance = module.instance.cast(module.instance.dynamic_type) if not isinstance(module, Worker): module.set_name(str(module.instance["myName"].string())) for attrib in module.instance.dereference().type.fields(): attrib_name = attrib.name if not attrib_name.endswith("_Itf"): continue stream = module.instance[attrib_name] stream_name = str(stream["myName"].string()) for connected in my_gdb.StdListPrinter(stream["connectedTo"]).children(): remote_stream = connected["stream"] remote_name = str(remote_stream["myName"].string()) remote_filter = remote_stream["myController"] remote_filter = remote_filter.cast(remote_filter.dynamic_type) if "DchanApexModel" in str(remote_filter.dynamic_type): # here, the remote_filter is wrong, because it's a DchanApexModel # instead of the real Module we want to connect. So we need to # retreive the right Module. remote_filter = None # we know it's a controller, so take all the fields of all the controllers if not "dma" in remote_name: for a_module in Worker.list_: for an_attrib in a_module.instance.dereference().type.fields(): an_attrib_name = an_attrib.name # and look for the Inteface field with matching name if not (an_attrib_name.startswith(remote_name) and an_attrib_name.endswith("_Itf")): continue # now, we know that we've got the right Module selected remote_filter = a_module.instance break if remote_filter is not None: break else: print ("COULDNT LOOKUP ", remote_name) actual_rmt_filter = Filter.key_to_value(str(remote_filter)) if actual_rmt_filter is None: continue connect_datastream_interface(stream, module, stream_name, remote_stream, actual_rmt_filter, remote_name) global loops loops = [l for l in compute_loops()] compute_loops_itf()
#############################################
[docs]def get_children(node): for itf in node.endpoints: if isinstance(itf, OwnerInterface) or \ isinstance(itf, OwneeInterface): continue if not itf.is_source: continue yield itf.get_other_side().comm_entity
loops = [] loops_itf = []
[docs]def compute_loops(node=None, node_parents=[]): if node is None: node = Filter.list_[1] child_parents = [node] child_parents.extend(node_parents) for child in get_children(node): if not child in node_parents: for lp in compute_loops(child, child_parents): yield lp else: yield [node]+child_parents[child_parents.index(child)::-1]
[docs]def compute_loops_itf(): loop_pairs = [zip(lp, lp[1:]) for lp in get_loops()] #loop_pairs = list of list of loop nodes (a-b, b-c, c-a)* for loop in loop_pairs: ifaces = [] for src, dst in loop: for itf in src.endpoints: if isinstance(itf, OwnerInterface) or \ isinstance(itf, OwneeInterface): continue if not itf.is_source: continue if itf.get_other_side().comm_entity == dst: ifaces.append(itf) break loops_itf.append(ifaces)
[docs]def get_loops(): return loops
[docs]def stop_on_deadlock(): deads = check_deadlock() if deads: my_gdb.push_stop_request(" /!\\ Deadlock detected in Loop %s /!\\" % ", ".join(["#%d" % d for d in deads]))
[docs]def check_deadlock(only_idx=None): dead = [] for idx, loop in enumerate(loops_itf): if only_idx is not None and only_idx != idx: continue for itf in loop: itf = itf.get_other_side() if not itf.blocking: break else: dead.append(idx) return dead
############################################# runtime_types = {}
[docs]def runtime_type(type_name): if type_name in runtime_types: return runtime_types[type_name] type_ = gdb.lookup_type(type_name) runtime_types[type_name] = type_ return type_