예제 #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()
예제 #2
0
    def _genAccessState(self, arch, state: State, verify_ssp: bool = False):
        transitions = [trans for trans in state.getaccess() if trans.getaccess() and not trans.getinmsg()] \
                      + state.getevictmiss()

        trans_dict = MultiDict()

        for transition in transitions:
            trans_dict[transition.getguard()] = transition

        statestr = ""

        for guard in trans_dict:

            ruleid = arch + "_" + str(state) + "_" + guard

            ccle_dot_state = self.ccle + "." + self.iState

            statestr += "rule \"" + ruleid + "\"" + self.nl
            statestr += self.tab + ccle_dot_state + " = " + arch + "_" + str(
                state) + self.nl

            statestr += self.gen_network_ready_test(trans_dict[guard])

            # Add network ready check here

            if verify_ssp:
                statestr += " & " + self._LockTest() + self.nl
            statestr += "==>" + self.nl
            if verify_ssp:
                statestr += self._LockAcquire() + self.end
            statestr += self.tab + self.tSEND + ruleid + "(" + self.cadr + ", m)" + self.end
            statestr += "endrule" + self.end + self.nl

        return statestr
예제 #3
0
    def _genArchState(self, arch, state: State):
        statestr = "case " + arch + "_" + state.getstatename() + ":" + self.nl
        statestr += "switch " + self.cinmsg + "." + self.cmtype + self.nl

        transitions = state.getdataack() + state.getremote() + \
                      [trans for trans in state.getaccess() if trans.getinmsg()]

        guard_list = []
        for transition in transitions:
            guard_list.append(transition.getguard())
        guard_list = list(set(guard_list))

        transitions.sort(key=lambda transition: (transition.getguard(
        ), transition.getcond(), transition.getfinalstate().getstatename()))

        op_string = ""
        for guard in guard_list:
            guard_trans = [
                transition for transition in transitions
                if transition.getguard() == guard
            ]
            op_string += self.gen_operation_str(arch, guard_trans)

        statestr += self._addtabs(op_string, 1)

        statestr += self.tab + " else return false" + self.end
        statestr += "endswitch" + self.end

        return self._addtabs(statestr, 1)
예제 #4
0
    def copy_trace_or_trans_list_rename_states(self,
                                               start_state: State,
                                               remote_trace: Union[Trace, List[Transition]],
                                               old_trans_to_new_trans_map: Dict[int, Transition],
                                               old_state_to_new_state_map: Dict[str, State],
                                               forbidden_guards: List[str]) \
            -> List[Transition]:

        remote_transitions = remote_trace
        if isinstance(remote_trace, Trace):
            remote_transitions = remote_trace.transitions

        remote_trace_trans_mod = []
        moving_start_state = start_state

        for ind in range(0, len(remote_transitions)):
            cur_transition = remote_transitions[ind]

            # Check if the current transition has been copied before
            cur_trans_hash = cur_transition.get_hash()
            if cur_trans_hash in old_trans_to_new_trans_map:
                remote_trace_trans_mod.append(
                    old_trans_to_new_trans_map[cur_trans_hash])
                moving_start_state = old_trans_to_new_trans_map[
                    cur_trans_hash].finalState
            else:
                if cur_transition.startState == cur_transition.finalState:
                    new_trans = self._CopyModifyTransition(
                        cur_transition, moving_start_state, moving_start_state)
                    start_state.addtransitions(new_trans)
                else:
                    final_state = None
                    if ind == len(remote_transitions) - 1:
                        final_state = cur_transition.finalState

                    moving_start_state, new_trans = self.copy_modify_state(
                        moving_start_state, remote_transitions[ind],
                        old_state_to_new_state_map, forbidden_guards,
                        final_state)

                remote_trace_trans_mod.append(new_trans)
                old_trans_to_new_trans_map[cur_trans_hash] = new_trans

        if remote_transitions[0].startState == remote_transitions[
                -1].finalState:
            remote_trace_trans_mod[-1].finalState = start_state

        remote_trace_trans_mod[0].startState = start_state

        return remote_trace_trans_mod
예제 #5
0
    def create_cc_dir_states(self, state_tuples: List[CcDirStateTuple]) -> Dict[str, State]:
        # Detect terminal states, every new state must have an edge that leads to a different new state
        cc_dir_start_state_tuples: Dict[Tuple[State, State], Tuple[State, State]] = {}
        cc_dir_final_state_tuples: Dict[Tuple[State, State], Tuple[State, State]] = {}
        for state_tuple in state_tuples:
            start_tuple = (state_tuple.ll_dir_start_state, state_tuple.hl_cc_start_state)
            cc_dir_start_state_tuples[start_tuple] = start_tuple
            final_tuple = (state_tuple.ll_dir_final_state, state_tuple.hl_cc_final_state)
            cc_dir_final_state_tuples[final_tuple] = final_tuple

        # Translate load and store accesses into message types
        new_access_list = []
        accesses = self.low_level.cache.init_state.access
        for access in accesses:
            for access_type in self.ll_access_map[access]:
                new_access_list.append(access_type)

        evict = self.low_level.cache.init_state.evict

        cc_dir_states = {}

        for cc_dir_state_tuple in set(cc_dir_final_state_tuples).intersection(cc_dir_start_state_tuples):
            state_str = self.new_state_name(str(cc_dir_state_tuple[0]), str(cc_dir_state_tuple[1]))
            new_state = State(state_str, new_access_list, evict)
            cc_dir_states[str(new_state)] = new_state

        return cc_dir_states
예제 #6
0
    def add_immed_request_access(self, state: State) -> None:
        for transition in state.gettransitions():
            # If an access can be performed without awaiting a response, important not request,
            # it can still make a request
            if transition.getaccess() in state.get_access_str():
                if transition.getoutmsg():
                    self.request_access.append(transition.getaccess())
                else:
                    self.immed_access.append(transition.getaccess())

            elif transition.getaccess() in state.get_evict_str():
                if transition.getoutmsg():
                    self.request_evict.append(transition.getaccess())
                else:
                    self.immed_evict.append(transition.getaccess())
            else:
                assert "Unrecognized access"
예제 #7
0
    def add_enter_access(self, state: State, traces: TraceSet) -> None:
        if state not in traces.final_state_dict:
            return

        enter_traces = traces.final_state_dict[state]

        for entry in enter_traces:
            for access in entry.access:
                if access:
                    if access in state.get_access_str(
                    ) and access not in self.enter_access:
                        self.enter_access.append(access)
                    elif access in state.get_evict_str(
                    ) and access not in self.enter_evict:
                        self.enter_evict.append(access)
                    else:
                        assert "Unrecognized access"
예제 #8
0
def convert_statenodes_to_states(transitions: List[Transition], access: List[str], evict: List[str]) -> Dict[str, State]:
    states = {}
    statetransmap = sort_states(transitions)
    for statename in statetransmap:
        # Create a new state object
        states.update({statename: State(statename, access, evict)})
        states[statename].addtransitions(statetransmap[statename])
    return states
예제 #9
0
 def cc_dir_state(rename_state_list: Dict[State, State], state_str: str,
                  state: State) -> State:
     if state_str not in rename_state_list:
         cc_dir_state = State(state_str, state.access, state.evict)
         rename_state_list[state_str] = cc_dir_state
         return cc_dir_state
     else:
         return rename_state_list[state_str]
예제 #10
0
    def _genAccessSendFunc(self, arch: Architecture, state: State):
        transitions = [trans for trans in state.getaccess() if trans.getaccess() and not trans.getinmsg()] \
                      + state.getevictmiss()

        trans_dict = MultiDict()

        for transition in transitions:
            trans_dict[transition.getguard()] = transition

        sendfctstr = ""

        for guard in trans_dict:
            ruleid = arch.get_unique_id_str() + "_" + str(state) + "_" + guard

            sendfctstr += self._genSendFunctionHeader(
                arch, ruleid, trans_dict[guard]) + self.nl

        return sendfctstr
예제 #11
0
    def _CopyModifyState(self, startstate, transition):
        newstate = State(
            startstate.getstatename() + "_" + transition.getguard(),
            self.access, self.evict)
        for datatrans in startstate.getdataack():
            newtrans = copy.copy(datatrans)
            newtrans.setstartstate(newstate)
            newstate.addtransitions(newtrans)

        for startset in transition.getfinalstate().getstatesets():
            startset.addstartstate(newstate)

        for endset in startstate.getendstatesets():
            endset.addendstate(newstate)

        # Create vertice
        startstate.addtransitions(
            self._CopyModifyTransition(transition, startstate, newstate))

        return newstate
예제 #12
0
    def _MergeGivenStates(self, mergestates, transitionmap, statesets):
        mergestates.sort(key=lambda x: len(x.getstatename()))
        # mergestates.sort(key=lambda x: len(x.getstatename()))

        # Make new state
        newstate = State(mergestates[0].getstatename(), self.access,
                         self.evict)

        for transition in transitionmap.values():
            newstate.addtransitions(transition[0])

        # Explore context
        startstatesets = []
        endstatesets = []

        for state in mergestates:
            startstatesets += state.getstartstatesets()
            endstatesets += state.getendstatesets()

        startstatesets = list(set(startstatesets))
        endstatesets = list(set(endstatesets))

        # Remove old states from all state sets
        for stateset in statesets.values():
            stateset.removestates(mergestates)

        # Now add new state to sets
        for stateset in startstatesets:
            stateset.addstartstate(newstate)

        for stateset in endstatesets:
            stateset.addendstate(newstate)

        # Update links
        for stateset in statesets.values():
            for state in stateset.getstates():
                for replacestate in mergestates:
                    state.replaceremotestate(replacestate, newstate)
예제 #13
0
    def _CopyState(self,
                   startstate: State,
                   guard,
                   stateset,
                   stablestates,
                   newstates,
                   dummy_state,
                   defer_operations: List[Tuple[Message,
                                                List[CommonTree]]] = None):
        newstate = State(
            self._CheckStateName(
                startstate.getstatename() + "__" + guard + "_" +
                stateset.getstablestate().getstatename(), stateset),
            self.access, self.evict)

        newstates.append(newstate)
        stateset.addendstate(newstate)

        #newstate.add_tail_list_defer_msg_operations(copy.copy(startstate.get_defer_msg_operation()))

        if defer_operations:
            newstate.add_tail_list_defer_msg_operations(defer_operations)

        for transition in startstate.getdataack():
            newtrans = copy.copy(transition)
            # Emit non deferred messages
            #newtrans.add_out_msg_list(copy.copy(transition.getoutmsg()))
            newtrans.setstartstate(newstate)

            if transition.getstartstate() == transition.getfinalstate():
                newtrans.setfinalstate(newstate)
            else:
                finalstate = [
                    finalstate for finalstate in stablestates
                    if finalstate == newtrans.getfinalstate().getstatename()
                ]
                if finalstate:
                    newtrans.setfinalstate(dummy_state)

                else:
                    finalstate = self._CopyState(newtrans.getfinalstate(),
                                                 guard, stateset, stablestates,
                                                 newstates, dummy_state,
                                                 defer_operations)

                    newtrans.setfinalstate(finalstate)
            newstate.addtransitions(newtrans)
        return newstate
예제 #14
0
    def _GenerateState(self, fork_state, remote_transition, stablestates,
                       deferfunc):
        newstates: List[State] = []

        finalsets = remote_transition.getfinalstate().getstatesets()
        if len(finalsets) > 1:
            print("Attention")
            return None

        newtrans = self._DeepCopyModifyTransitionOperation(
            remote_transition, fork_state, fork_state)

        # Defer message
        defer_tuples = deferfunc(remote_transition, newtrans)

        unique_dummy_state = State("Placeholder")

        newstate = self._CopyState(fork_state, remote_transition.getguard(),
                                   finalsets[0], stablestates, newstates,
                                   unique_dummy_state, defer_tuples)

        newtrans.setfinalstate(newstate)
        fork_state.addremotemiss(newtrans)

        # ADD DEFER TRANSITIONS TO THE FIELD SINCE THERE EXIST TRACES THAT NEED TO BE STORED,
        # THINK ABOUT NOT SINGLE TRANSITION REMOTE REQUESTS

        # If the remote transition is part of a longer trace, it is deferred
        # Take the last new_state
        for newstate in newstates:
            for transition in newstate.setTrans:
                if transition.finalState == unique_dummy_state:
                    if defer_tuples:
                        transition.outMsg = copy.copy(transition.outMsg)
                        transition.operation = copy.copy(transition.operation)
                        # Add defer operation to remote_transition
                        for defer_tuple in defer_tuples:
                            transition.addoutmsg(defer_tuple[0])
                            transition.add_operation_list(defer_tuple[1])
                    # Set final state to remote_transition final state
                    transition.finalState = remote_transition.finalState

        return newstate
예제 #15
0
    def cc_dir_loop_transitions(self, state_map_dict: Dict[State, List[State]]) -> List[Transition]:
        all_transitions = []
        for cc_dir_state in state_map_dict:
            for mapped_single_layer_state in state_map_dict[cc_dir_state]:
                if str(mapped_single_layer_state) in self.low_level.directory.stable_state_str:
                    continue
                for transition in mapped_single_layer_state.gettransitions():
                    if transition.comm_class != CommunicationClassification.resp:
                        continue

                    # if the transition loops
                    if transition.startState == transition.finalState and not transition.access:
                        new_trans = copy.copy(transition)
                        new_state = State(str(cc_dir_state), transition.startState.access, transition.startState.evict)
                        new_trans.startState = new_state
                        new_trans.finalState = new_state
                        all_transitions.append(new_trans)

        ret_transitions = self.trans_list_hash_reduction(all_transitions)
        return ret_transitions
예제 #16
0
    def copy_modify_state(self,
                          startstate: State,
                          transition: Transition,
                          old_state_to_new_state_map: Dict[str, State],
                          forbidden_guards: List[str],
                          final_state: [State, None] = None):
        # If a known final state exists, then
        if final_state:
            newstate = final_state
            if str(final_state) in old_state_to_new_state_map:
                newstate = old_state_to_new_state_map[str(final_state)]
        else:
            new_state_str = startstate.getstatename(
            ) + "_" + transition.getguard()
            if new_state_str in old_state_to_new_state_map:
                newstate = old_state_to_new_state_map[new_state_str]
            else:
                newstate = State(new_state_str, self.access, self.evict)
                old_state_to_new_state_map[new_state_str] = newstate

                # The new_state replaces the final state so it must possess all local access permissions
                for trans in transition.startState.setTrans:
                    if str(trans.inMsg) in forbidden_guards:
                        continue

                    if trans.startState == trans.finalState:
                        new_trans = self._CopyModifyTransition(
                            trans, newstate, newstate)
                        newstate.addtransitions(new_trans)

                for trans in transition.finalState.setTrans:
                    if str(trans.inMsg) in forbidden_guards:
                        continue

                    if trans.startState == trans.finalState:
                        new_trans = self._CopyModifyTransition(
                            trans, newstate, newstate)
                        newstate.addtransitions(new_trans)

                # The new_state replaces the final state so it must possess all local access permissions
                for trans in startstate.setTrans:
                    if str(trans.inMsg) in forbidden_guards:
                        continue

                    if trans.startState == trans.finalState:
                        new_trans = self._CopyModifyTransition(
                            trans, newstate, newstate)
                        newstate.addtransitions(new_trans)

                for startset in transition.getfinalstate().getstatesets():
                    startset.addstartstate(newstate)

                for endset in startstate.getendstatesets():
                    endset.addendstate(newstate)

        # Create vertice
        new_trans = self._CopyModifyTransition(transition, startstate,
                                               newstate)
        startstate.addtransitions(new_trans)

        return newstate, new_trans