package net.sf.orcc.backends.promela.transform; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.orcc.df.Action; import net.sf.orcc.df.Actor; import net.sf.orcc.df.FSM; import net.sf.orcc.df.State; import net.sf.orcc.df.Transition; import net.sf.orcc.graph.Edge; import net.sf.orcc.ir.Var; public class Scheduler { private Set<Schedule> schedules = new HashSet<Schedule>(); private Set<List<Schedule>> scheduleCases; private State initialState = null; private Map<Var, List<Action>> schedVarUpdate = new HashMap<Var, List<Action>>(); private Map<Var, List<Action>> schedVarReset = new HashMap<Var, List<Action>>(); private Map<Action, Map<Var, Set<Var>>> localVarDep = new HashMap<Action, Map<Var, Set<Var>>>(); private Map<State, Set<Var>> stateToRelevantVars = new HashMap<State, Set<Var>>(); private Set<Var> schedulingVars = null; public Set<Var> getSchedulingVars() { return schedulingVars; } private Actor actor; public Scheduler(Actor actor, FSM fsm) { this.actor = actor; if (fsm != null) { this.initialState = fsm.getInitialState(); } } public void addLocalVarDep(Action action, Var var, Set<Var> localDep) { if (!localVarDep.containsKey(action)) { localVarDep.put(action, new HashMap<Var, Set<Var>>()); } if (!localVarDep.get(action).containsKey(var)) { localVarDep.get(action).put(var, new HashSet<Var>()); } localVarDep.get(action).get(var).addAll(localDep); } public void addSchedule(Schedule s) { schedules.add(s); } public void addvarReset(Var var, Action action) { if (!schedVarReset.containsKey(var)) { schedVarReset.put(var, new ArrayList<Action>()); } schedVarReset.get(var).add(action); } public void addvarUpdate(Var var, Action action) { if (!schedVarUpdate.containsKey(var)) { schedVarUpdate.put(var, new ArrayList<Action>()); } schedVarUpdate.get(var).add(action); } public void buildSchedulingCases() { /*for (Schedule schedule : schedules) { if (schedule.getPotentialEndStates().size()==1) { for (State state : schedule.getPotentialEndStates()) { schedule.setEndState(state); } } }*/ scheduleCases = new HashSet<List<Schedule>>(); Set<State> toVisit = new HashSet<State>(); toVisit.add(initialState); Set<State> visitedStates = new HashSet<State>(); while (!toVisit.isEmpty()) { visitedStates.addAll(toVisit); Set<State> newStates = new HashSet<State>(); for (State s : toVisit) { for (Schedule sched : getSchedulesStartingAt(s)) { List<Schedule> schedCase; if (s != initialState) { schedCase = getSchedCaseEndingAt(s); } else { schedCase = new ArrayList<Schedule>(); } if (!visitedStates.contains(sched.getEndState())) { newStates.add(sched.getEndState()); } schedCase.add(sched); scheduleCases.add(schedCase); } } toVisit = newStates; } } public State getInitialState() { return initialState; } public Actor getActor() { return actor; } public Set<Var> getLocalVarDep(Action action, Var var) { if (localVarDep.containsKey(action) && localVarDep.get(action).containsKey(var)) { return localVarDep.get(action).get(var); } else { return new HashSet<Var>(); } } private List<Schedule> getSchedCaseEndingAt(State state) { for (List<Schedule> list : scheduleCases) { if (state == list.get(list.size() - 1).getEndState()) return new ArrayList<Schedule>(list); } return null; } public Set<List<Schedule>> getScheduleCases() { return scheduleCases; } public Set<Schedule> getSchedules() { return schedules; } public Set<Schedule> getSchedulesStartingAt(State state) { Set<Schedule> set = new HashSet<Schedule>(); for (Schedule s : this.getSchedules()) { if (s.getInitState() == state) { set.add(s); } } return set; } public Map<Var, List<Action>> getSchedVarReset() { return schedVarReset; } public Map<Var, List<Action>> getSchedVarUpdate() { return schedVarUpdate; } public void makeDummyFSM() { schedules.clear(); if (actor.hasFsm()) { for (State state : actor.getFsm().getStates()) { for (Edge edge : state.getOutgoing()) { Transition trans = (Transition) edge; Schedule s = new Schedule(state, trans.getAction()); s.getSequence().add(trans.getAction()); s.setEndState((State) edge.getTarget()); schedules.add(s); } // States outside FSM is in every state.. for (Action action : actor.getActionsOutsideFsm()) { Schedule s = new Schedule(state, action); s.getSequence().add(action); s.setEndState(state); schedules.add(s); } } } else { for (Action a : actor.getActions()) { Schedule s = new Schedule(null, a); s.getSequence().add(a); schedules.add(s); } } } public String toString() { String s = "<fsm initial= \"" + this.initialState + "\">\n"; for (Schedule sched : schedules) { s += "<transition action=\"" + sched.getEnablingAction() + "\" dst=\"" + sched.getEndState() + "\" src=\"" + sched.getInitState() + "\"/>\n"; } s += "</fsm>\n"; return s; } public Map<State, Set<Var>> getStateToRelevantVars() { return stateToRelevantVars; } public void setSchedulingVars(Set<Var> stateVars) { schedulingVars=stateVars; } }