Beispiel #1
0
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()
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
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)