def create_trace_tree(state: State, stablestates: List[str]) -> List[List[TraceNodeObj]]: tracetree = ForkTree() basenode = tracetree.insertnode(TraceNodeObj(state)) # Initially get loops from states once nextlist = get_trans_finalstates_loop([basenode], state.gettransitions()) while nextlist: endnodes = [] for nextnode in nextlist: endnodes += tracetree.appenddata(nextnode[1], nextnode[0]) nextlist = [] for node in endnodes: state = node.getdata().get_state() if not [ stateid for stateid in stablestates if state.getstatename() == stateid ]: nextlist += get_trans_finalstates([node], state.gettransitions()) return tracetree.gettraces()
def ll_proxy_dir_trace( self, ll_dir_trace: Trace, ll_proxy_trace: Trace, ll_remote_traces: Union[List[Trace], None]) -> List[List[Transition]]: cache_transitions = [] ll_dir_transistions = [ copy.copy(trans) for trans in ll_dir_trace.transitions ] ll_prox_transitions = [ copy.copy(trans) for trans in ll_proxy_trace.transitions ] ll_remote_transitions = [] if ll_remote_traces: for ll_remote_trace in ll_remote_traces: if ll_remote_trace: ll_remote_transitions += [ copy.copy(trans) for trans in ll_remote_trace.transitions ] trace_tree = ForkTree() basenode = trace_tree.insertnode( TraceNodeObj(ll_prox_transitions[0].outMsg, ll_prox_transitions[0])) nextlist = self.get_next_transitions([basenode], ll_dir_transistions, ll_prox_transitions, ll_remote_transitions) while nextlist: endnodes = [] for nextnode in nextlist: endnodes += trace_tree.appenddata(nextnode[1], nextnode[0]) nextlist = [] for node in endnodes: nextlist += self.get_next_transitions([node], ll_dir_transistions, ll_prox_transitions, ll_remote_transitions) new_traces = trace_tree.gettraces() # Check the length of each trace and remove to short traces, brute force state exploration # sort out traces that are too short indicating that not all traces have been used valid_traces = [] for new_trace in new_traces: trans_sequence = [node.transition for node in new_trace] # Convert to standard trace if set(ll_dir_transistions + ll_prox_transitions).issubset( set(trans_sequence)): valid_traces.append(new_trace) # convert traces into transitions for valid_trace in valid_traces: cache_transitions.append( self.convert_traces_to_cc_dir_transition_traces_list( valid_trace, ll_remote_transitions)) return cache_transitions
def single_access_find_next_tuple(self, cur_tuple: Tuple[Machine], handle_evicts: bool = True): # If no access can be found this is not as bad as if multiple accesses cannot be served new_tuples = {} new_traces = [] request_machine: Machine = cur_tuple[0] remote_machines: List[Machine] = cur_tuple[1:] # self.debug_assert(cur_tuple) for trace in request_machine.arch.traces.start_state_dict[request_machine.final_state]: if not trace.access: continue else: evict_exists = 0 for access in trace.access: if access in request_machine.arch.evict_def and not handle_evicts: evict_exists = 1 break if evict_exists: continue trace_tree = ForkTree() basenode = trace_tree.insertnode(TraceNodeObj(request_machine, trace)) nextlist = self.find_next_trace_nodes([basenode], remote_machines) while nextlist: endnodes = [] for nextnode in nextlist: endnodes += trace_tree.append_data_list(nextnode[1], nextnode[0]) nextlist = [] for node in endnodes: nextlist += self.find_next_trace_nodes([node], remote_machines) new_traces += self.validate_traces(trace_tree.gettraces()) if self.longest_trace: longest_new_traces = self.find_longest_traces(new_traces) # Register transactions taken self.make_new_system_tuple(cur_tuple, [x for x in new_traces if x not in longest_new_traces]) new_traces = longest_new_traces new_system_tuples = self.make_new_system_tuple(cur_tuple, new_traces) for new_system_tuple in new_system_tuples: new_tuples[new_system_tuple.__hash__()] = new_system_tuple return new_tuples