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 tree_find_children(self, operation_str: str, operation_tree: ForkTree) -> bool: cur_children = operation_tree.get_direct_children() for child_node in cur_children: node_str = child_node.getdata()[1] if node_str == operation_str: # Found output string as children, select children to be next operation_tree.set_cur_node(child_node) return True return False
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
def __init__(self, startstate, guard, finalstate): assert isinstance(startstate, StateNode) assert isinstance(finalstate, StateNode) assert isinstance(guard, str) self.messages = {} self.trans = [] self.startState = startstate self.interfinalState = finalstate.getstatename() self.access = guard self.TransTree = ForkTree() self.ifTree = 0 self.TransTree.insertnode(Transition(startstate, finalstate, guard)) self.IfTree = ForkTree()
def endifconstr(self): endnodes = [] if self.ifTree: curnode = self.IfTree.getbasenode() prenode = self.TransTree.popdelcurnode(curnode) # Get all end nodes endnodes = self.IfTree.getendnodes() ret = self.TransTree.appendnodes(endnodes, prenode) if not ret: perror( "Nodes with unknown predecessors could not be inserted into tree" ) # Clear tree self.IfTree = ForkTree() self.ifTree = 0 return endnodes
def check_operation_tree(self, operation_tree: ForkTree): # Check for each node, whether not more than one operation assignment exists for node in operation_tree.get_nodes(): cnt = 0 for child in node.getsuccessors(): # The data is a tuple(operation, operation_string) if child.getdata()[0].getText( ) == self.tCOND and child.getdata()[0].getText( ) == self.tNCOND: cnt += 1 assert cnt <= 1, "More than one children found that is not a condition" pass
def convert_operation_tree_wo_case(self, operation_tree: ForkTree) -> str: # At the last child nodes print return true at the end! base_node = operation_tree.get_base_node() return self._addtabs(self.tree_node_to_string(base_node), 1)
def gen_operation_tree(self, arch: str, transitions: List[Transition]) -> ForkTree: # Make the root node operation_tree = ForkTree() check_guard = [] for transition in transitions: check_guard.append(transition.getguard()) assert len( set(check_guard) ) == 1, "Transitions to create operation tree from have different guards" # Node data is a tuple (operation object, operation string) guard = check_guard.pop() base_node = operation_tree.insertnode( (guard, "case " + guard + ":" + self.nl)) for transition in transitions: # Reset tree to base node operation_tree.set_cur_node(base_node) for operation in transition.operation: # Get children access_str = self.process_operation(operation, arch, transition) if not self.tree_find_children(access_str, operation_tree): operation_tree.insertnode((operation, access_str)) # After last operation insert final state final_state_str = self._genFinalState(arch, transition) if not self.tree_find_children(final_state_str, operation_tree): operation_tree.insertnode((final_state_str, final_state_str)) # Set access permission access_permission_str = self._genArchAccess(transition) if not self.tree_find_children(access_permission_str, operation_tree): operation_tree.insertnode( (access_permission_str, access_permission_str)) return operation_tree
class Transaction: def __init__(self, startstate, guard, finalstate): assert isinstance(startstate, StateNode) assert isinstance(finalstate, StateNode) assert isinstance(guard, str) self.messages = {} self.trans = [] self.startState = startstate self.interfinalState = finalstate.getstatename() self.access = guard self.TransTree = ForkTree() self.ifTree = 0 self.TransTree.insertnode(Transition(startstate, finalstate, guard)) self.IfTree = ForkTree() ######################################################################################################################## # DATA ACCESS ######################################################################################################################## def gettransitions(self): return self.trans def getMessageMap(self): return self.messages ######################################################################################################################## # TRANSITION TREE ######################################################################################################################## def getstartstate(self): return self.startState def getinterfinalstate(self): return self.interfinalState def getnrtransitions(self): return len(self.trans) + 1 ######################################################################################################################## # GENERAL ######################################################################################################################## def getcurtransition(self): if self.ifTree: return self.IfTree.getcurnode().getdata() else: return self.TransTree.getcurnode().getdata() def getcurtransitionode(self): if self.ifTree: return self.IfTree.getcurnode() else: return self.TransTree.getcurnode() def addoperation(self, operation): if self.ifTree: childs = self.IfTree.getchildnodes(self.IfTree.getcurnode()) for entry in childs: entry.getdata().addoperation(operation) else: return self.TransTree.getcurnode().getdata().addoperation( operation) def addoutmsg(self, message): if self.ifTree: childs = self.IfTree.getchildnodes(self.IfTree.getcurnode()) for entry in childs: entry.getdata().addoutmsg(message) else: return self.TransTree.getcurnode().getdata().addoutmsg(message) def setfinalstate(self, finalstate): if self.ifTree: childs = self.IfTree.getchildnodes(self.IfTree.getcurnode()) for entry in childs: entry.getdata().getfinalstate().setstatename(finalstate) else: return self.TransTree.getcurnode().getdata().getfinalstate( ).setstatename(finalstate) ######################################################################################################################## # IF TREE ######################################################################################################################## def newifconstr(self): if not self.ifTree: self.IfTree.insertnode(self.getcurtransition(), self.getcurtransitionode()) self.ifTree = 1 def newifelse(self): curnode = self.IfTree.getcurnode() return self.IfTree.insertnode(copy.deepcopy(curnode.getdata()), curnode) def endif(self): return self.IfTree.popcurnode() def endifconstr(self): endnodes = [] if self.ifTree: curnode = self.IfTree.getbasenode() prenode = self.TransTree.popdelcurnode(curnode) # Get all end nodes endnodes = self.IfTree.getendnodes() ret = self.TransTree.appendnodes(endnodes, prenode) if not ret: perror( "Nodes with unknown predecessors could not be inserted into tree" ) # Clear tree self.IfTree = ForkTree() self.ifTree = 0 return endnodes ######################################################################################################################## # TRANSITION TREE ######################################################################################################################## def newwhen(self, startstate, finalstate, guard, prenode): return self.TransTree.insertnode( Transition(startstate, finalstate, guard), prenode) def endwhen(self): # Push if tree at end of transition tree return self.TransTree.popcurnode() def pushtransition(self): # Extract tree into simple transitions self.trans += self.TransTree.treetolist() ######################################################################################################################## # MESSAGE SECTION ######################################################################################################################## def addmessage(self, mname, message): self.messages.update({mname: message}) def getmessage(self, mname): msg = self.messages.get(mname) if not msg: perror("KeyError: Message was never instantiated") return msg ######################################################################################################################## # DEBUG ######################################################################################################################## def pbase(self): return ("Transaction:: " + "Start: " + self.startState.pstate() + " *Guard: " + self.access + " Final: " + self.interfinalState)