private Hashtable<FlagState, FlagState> targetFState;
private Vector<Integer> ancestorCores;
private Vector<Integer> childCores;
+ private Hashtable<FlagState, Vector<Integer>> allyCores;
+ private Hashtable<TaskDescriptor, Vector<FlagState>> td2fs;
public Schedule(int coreNum) {
super();
this.targetCores = null;
this.targetFState = null;
this.ancestorCores = null;
+ this.allyCores = null;
+ this.td2fs = null;
}
public int getCoreNum() {
}
return targetFState.get(fstate);
}
+
+ public Hashtable<FlagState, Vector<Integer>> getAllyCoreTable() {
+ return this.allyCores;
+ }
+
+ public Vector<Integer> getAllyCores(FlagState fstate) {
+ if(this.allyCores == null) {
+ return null;
+ }
+ return this.allyCores.get(fstate);
+ }
+
+ public Hashtable<TaskDescriptor, Vector<FlagState>> getTd2FsTable() {
+ return this.td2fs;
+ }
+
+ public Vector<FlagState> getFStates4TD(TaskDescriptor td) {
+ if(this.td2fs == null) {
+ return null;
+ }
+ return this.td2fs.get(td);
+ }
public void addTargetCore(FlagState fstate, Integer targetCore/*, Integer num*/) {
if(this.targetCores == null) {
this.targetFState.put(fstate, tfstate);
//}
}
+
+ public void addAllyCore(FlagState fstate, Integer targetCore/*, Integer num*/) {
+ if(this.allyCores == null) {
+ this.allyCores = new Hashtable<FlagState, Vector<Integer>>();
+ }
+ if(!this.allyCores.containsKey(fstate)) {
+ this.allyCores.put(fstate, new Vector<Integer>());
+ }
+ if((this.coreNum != targetCore.intValue()) && (!this.allyCores.get(fstate).contains(targetCore))) {
+ this.allyCores.get(fstate).add(targetCore); // there may have some duplicate items,
+ // which reflects probabilities.
+ }
+ }
+
+ public void addFState4TD(TaskDescriptor td, FlagState fstate) {
+ if(this.td2fs == null) {
+ this.td2fs = new Hashtable<TaskDescriptor, Vector<FlagState>>();
+ }
+ if(!this.td2fs.containsKey(td)) {
+ this.td2fs.put(td, new Vector<FlagState>());
+ }
+ if(!this.td2fs.get(td).contains(fstate)) {
+ this.td2fs.get(td).add(fstate);
+ }
+ }
public Vector<TaskDescriptor> getTasks() {
return tasks;
ClassDescriptor pcd = pfs.getClassDescriptor();
ClassNode pcNode = cdToCNodes.get(pcd);
- ScheduleEdge sEdge = new ScheduleEdge(sNode, "new", root, 0);//new ScheduleEdge(sNode, "new", cd, 0);
+ ScheduleEdge sEdge = new ScheduleEdge(sNode, "new", root, ScheduleEdge.NEWEDGE, 0);
sEdge.setFEdge(pfe);
sEdge.setSourceCNode(pcNode);
sEdge.setTargetCNode(cNode);
}
cdToCNodes = null;
- // Do topology sort of the ClassNodes and ScheduleEdges.
- Vector<ScheduleEdge> ssev = new Vector<ScheduleEdge>();
- Vector<ScheduleNode> tempSNodes = ClassNode.DFS.topology(scheduleNodes, ssev);
- scheduleNodes.removeAllElements();
- scheduleNodes = tempSNodes;
- tempSNodes = null;
- scheduleEdges.removeAllElements();
- scheduleEdges = ssev;
- ssev = null;
- sorted = true;
+ // Create 'associate' edges between the ScheduleNodes.
+ /*Iterator<TaskDescriptor> it_tasks = (Iterator<TaskDescriptor>)state.getTaskSymbolTable().getDescriptorsIterator();
+ while(it_tasks.hasNext()) {
+ TaskDescriptor td = it_tasks.next();
+ int numParams = td.numParameters();
+ if(!(numParams > 1)) {
+ // single parameter task
+ continue;
+ }
+ ClassNode[] cNodes = new ClassNode[numParams];
+ for(i = 0; i < numParams; ++i) {
+ cNodes[i] = this.cd2ClassNode.get(td.getParamType(i).getClassDesc());
+ }
+ Vector<FEdge> fev = (Vector<FEdge>)taskanalysis.getFEdgesFromTD(td);
+ // for each fedge associated to this td, create an associate ScheduleEdge
+ // from the ClassNode containg this FEdge to every other ClassNode representing
+ // other parameters.
+ for(i = 0; i < fev.size(); ++i) {
+ FEdge tmpfe = fev.elementAt(i);
+ for(int j = 0; j < numParams; ++j) {
+ if(j == tmpfe.getIndex()) {
+ continue;
+ }
+ FlagState fs = (FlagState)tmpfe.getSource();
+ ScheduleEdge se = new ScheduleEdge(cNodes[j].getScheduleNode(), "associate", fs, ScheduleEdge.ASSOCEDGE, 0);
+ se.setFEdge(tmpfe);
+ se.setSourceCNode(cNodes[i]);
+ se.setTargetCNode(cNodes[j]);
+ // targetFState is always null
+ cNodes[i].getScheduleNode().addAssociateSEdge(se);
+ // scheduleEdges only holds new/transmit edges
+ //scheduleEdges.add(se);
+ fs.addAlly(se);
+ }
+ }
+ }*/
// Break down the 'cycle's
- for(i = 0; i < toBreakDown.size(); i++ ) {
- cloneSNodeList(toBreakDown.elementAt(i), false);
- }
- toBreakDown = null;
+ try {
+ for(i = 0; i < toBreakDown.size(); i++ ) {
+ cloneSNodeList(toBreakDown.elementAt(i), false);
+ }
+ toBreakDown = null;
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(-1);
+ }
// Remove fake 'new' edges
for(i = 0; i < scheduleEdges.size(); i++) {
- ScheduleEdge se = scheduleEdges.elementAt(i);
+ /*if(ScheduleEdge.NEWEDGE != scheduleEdges.elementAt(i).getType()) {
+ continue;
+ }*/
+ ScheduleEdge se = (ScheduleEdge)scheduleEdges.elementAt(i);
if((0 == se.getNewRate()) || (0 == se.getProbability())) {
scheduleEdges.removeElement(se);
scheduleNodes.removeElement(se.getTarget());
}
}
+ // Do topology sort of the ClassNodes and ScheduleEdges.
+ Vector<ScheduleEdge> ssev = new Vector<ScheduleEdge>();
+ Vector<ScheduleNode> tempSNodes = ClassNode.DFS.topology(scheduleNodes, ssev);
+ scheduleNodes.removeAllElements();
+ scheduleNodes = tempSNodes;
+ tempSNodes = null;
+ scheduleEdges.removeAllElements();
+ scheduleEdges = ssev;
+ ssev = null;
+ sorted = true;
+
SchedulingUtil.printScheduleGraph("scheduling_ori.dot", this.scheduleNodes);
}
Hashtable<ScheduleNode, Vector<FEdge>> sn2fes = new Hashtable<ScheduleNode, Vector<FEdge>>();
ScheduleNode preSNode = null;
for(i = scheduleEdges.size(); i > 0; i--) {
- ScheduleEdge se = scheduleEdges.elementAt(i-1);
- if(preSNode == null) {
- preSNode = (ScheduleNode)se.getSource();
- }
- if(se.getIsNew()) {
+ ScheduleEdge se = (ScheduleEdge)scheduleEdges.elementAt(i-1);
+ if(ScheduleEdge.NEWEDGE == se.getType()) {
+ if(preSNode == null) {
+ preSNode = (ScheduleNode)se.getSource();
+ }
+
boolean split = false;
FEdge fe = se.getFEdge();
if(fe.getSource() == fe.getTarget()) {
// back edge
- int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
- int rate = 0;
- if(repeat > 1){
- for(int j = 1; j< repeat; j++ ) {
- cloneSNodeList(se, true);
- }
- se.setNewRate(1);
- se.setProbability(100);
- }
try {
- rate = (int)Math.ceil(se.getListExeTime()/ calInExeTime(se.getSourceFState()));
+ int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
+ int rate = 0;
+ if(repeat > 1){
+ for(int j = 1; j< repeat; j++ ) {
+ cloneSNodeList(se, true);
+ }
+ se.setNewRate(1);
+ se.setProbability(100);
+ }
+ try {
+ rate = (int)Math.ceil(se.getListExeTime()/ calInExeTime(se.getSourceFState()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ for(int j = rate - 1; j > 0; j--) {
+ for(int k = repeat; k > 0; k--) {
+ cloneSNodeList(se, true);
+ }
+ }
} catch (Exception e) {
e.printStackTrace();
- }
- for(int j = rate - 1; j > 0; j--) {
- for(int k = repeat; k > 0; k--) {
- cloneSNodeList(se, true);
- }
+ System.exit(-1);
}
} else {
// if preSNode is not the same as se's source ScheduleNode
// handle any ScheduleEdges previously put into fe2ses whose source ScheduleNode is preSNode
boolean same = (preSNode == se.getSource());
if(!same) {
+ // check the topology sort, only process those after se.getSource()
if(preSNode.getFinishingTime() < se.getSource().getFinishingTime()) {
if(sn2fes.containsKey(preSNode)) {
Vector<FEdge> fes = sn2fes.remove(preSNode);
preSNode = (ScheduleNode)se.getSource();
}
- // if fe is the last task inside this ClassNode, delay the expanding and merging until we find all such 'nmew' edges
+ // if fe is the last task inside this ClassNode, delay the expanding and merging until we find all such 'new' edges
// associated with a last task inside this ClassNode
if(!fe.getTarget().edges().hasNext()) {
if(fe2ses.get(fe) == null) {
if(sn2fes.get((ScheduleNode)se.getSource()) == null) {
sn2fes.put((ScheduleNode)se.getSource(), new Vector<FEdge>());
}
- fe2ses.get(fe).add(se);
- sn2fes.get((ScheduleNode)se.getSource()).add(fe);
+ if(!fe2ses.get(fe).contains(se)) {
+ fe2ses.get(fe).add(se);
+ }
+ if(!sn2fes.get((ScheduleNode)se.getSource()).contains(fe)) {
+ sn2fes.get((ScheduleNode)se.getSource()).add(fe);
+ }
} else {
// As this is not a last task, first handle available ScheduleEdges previously put into fe2ses
if((same) && (sn2fes.containsKey(preSNode))) {
}
private void handleScheduleEdge(ScheduleEdge se, boolean merge) {
- int rate = 0;
- int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
- if(merge) {
- try {
- rate = (int)Math.ceil((se.getTransTime() - calInExeTime(se.getSourceFState()))/ se.getListExeTime());
- if(rate < 0 ) {
- rate = 0;
+ try {
+ int rate = 0;
+ int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
+ if(merge) {
+ try {
+ rate = (int)Math.ceil((se.getTransTime() - calInExeTime(se.getSourceFState()))/ se.getListExeTime());
+ if(rate < 0 ) {
+ rate = 0;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
}
- } catch (Exception e) {
- e.printStackTrace();
- }
- if(0 == rate) {
+ if(0 == rate) {
+ // clone the whole ScheduleNode lists starting with se's target
+ for(int j = 1; j < repeat; j++ ) {
+ cloneSNodeList(se, true);
+ }
+ se.setNewRate(1);
+ se.setProbability(100);
+ } else {
+ repeat -= rate;
+ if(repeat > 0){
+ // clone the whole ScheduleNode lists starting with se's target
+ for(int j = 0; j < repeat; j++ ) {
+ cloneSNodeList(se, true);
+ }
+ se.setNewRate(rate);
+ se.setProbability(100);
+ }
+ }
+ // merge the original ScheduleNode to the source ScheduleNode
+ ((ScheduleNode)se.getSource()).mergeSEdge(se);
+ scheduleNodes.remove(se.getTarget());
+ scheduleEdges.remove(se);
+ // As se has been changed into an internal edge inside a ScheduleNode,
+ // change the source and target of se from original ScheduleNodes into ClassNodes.
+ se.setTarget(se.getTargetCNode());
+ se.setSource(se.getSourceCNode());
+ se.getTargetCNode().addEdge(se);
+ } else {
// clone the whole ScheduleNode lists starting with se's target
for(int j = 1; j < repeat; j++ ) {
cloneSNodeList(se, true);
}
se.setNewRate(1);
se.setProbability(100);
- } else {
- repeat -= rate;
- if(repeat > 0){
- // clone the whole ScheduleNode lists starting with se's target
- for(int j = 0; j < repeat; j++ ) {
- cloneSNodeList(se, true);
- }
- se.setNewRate(rate);
- se.setProbability(100);
- }
- }
- // merge the original ScheduleNode to the source ScheduleNode
- ((ScheduleNode)se.getSource()).mergeSEdge(se);
- scheduleNodes.remove(se.getTarget());
- scheduleEdges.remove(se);
- // As se has been changed into an internal edge inside a ScheduleNode,
- // change the source and target of se from original ScheduleNodes into ClassNodes.
- se.setTarget(se.getTargetCNode());
- se.setSource(se.getSourceCNode());
- } else {
- // clone the whole ScheduleNode lists starting with se's target
- for(int j = 1; j < repeat; j++ ) {
- cloneSNodeList(se, true);
}
- se.setNewRate(1);
- se.setProbability(100);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(-1);
}
}
- private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) {
- Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>();
+ private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) throws Exception {
+ Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>(); // hashtable from classnode in orignal se's targe to cloned one
ScheduleNode csNode = (ScheduleNode)((ScheduleNode)sEdge.getTarget()).clone(cn2cn, 0);
scheduleNodes.add(csNode);
for(i = 0; i < inedges.size(); i++) {
ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i);
ScheduleEdge se;
- if(tse.getIsNew()) {
- se = new ScheduleEdge(csNode, "new", tse.getFstate(), tse.getIsNew(), 0); //new ScheduleEdge(csNode, "new", tse.getClassDescriptor(), tse.getIsNew(), 0);
+ switch(tse.getType()) {
+ case ScheduleEdge.NEWEDGE: {
+ se = new ScheduleEdge(csNode, "new", tse.getFstate(), tse.getType(), 0);
se.setProbability(100);
se.setNewRate(1);
- } else {
- se = new ScheduleEdge(csNode, "transmit", tse.getFstate(), false, 0);//new ScheduleEdge(csNode, "transmit", tse.getClassDescriptor(), false, 0);
+ break;
+ }
+ case ScheduleEdge.TRANSEDGE: {
+ se = new ScheduleEdge(csNode, "transmit", tse.getFstate(), tse.getType(), 0);
+ se.setProbability(tse.getProbability());
+ se.setNewRate(tse.getNewRate());
+ break;
+ }
+ /*case ScheduleEdge.ASSOCEDGE: {
+ se = new ScheduleEdge(csNode, "associate", tse.getFstate(), tse.getType(), 0);
+ se.setProbability(tse.getProbability());
+ se.setNewRate(tse.getNewRate());
+ break;
+ }*/
+ default: {
+ throw new Exception("Error: not valid ScheduleEdge here");
+ }
}
se.setSourceCNode(tse.getSourceCNode());
se.setTargetCNode(cn2cn.get(tse.getTargetCNode()));
scheduleEdges.add(se);
}
inedges = null;
+
+ // in associate ScheduleEdgs
+ /*inedges = ((ScheduleNode)sEdge.getTarget()).getInAssociateSEdges();
+ for(i = 0; i < inedges.size(); i++) {
+ ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i);
+ ScheduleEdge se;
+ switch(tse.getType()) {
+ case ScheduleEdge.ASSOCEDGE: {
+ se = new ScheduleEdge(csNode, "associate", tse.getFstate(), tse.getType(), 0);
+ se.setProbability(tse.getProbability());
+ se.setNewRate(tse.getNewRate());
+ break;
+ }
+ default: {
+ throw new Exception("Error: not valid ScheduleEdge here");
+ }
+ }
+ se.setSourceCNode(tse.getSourceCNode());
+ se.setTargetCNode(cn2cn.get(tse.getTargetCNode()));
+ se.setFEdge(tse.getFEdge());
+ se.setTargetFState(tse.getTargetFState());
+ se.setIsclone(true);
+ ((ScheduleNode)tse.getSource()).addAssociateSEdge(se);
+ }
+ inedges = null;*/
} else {
sEdge.getTarget().removeInedge(sEdge);
sEdge.setTarget(csNode);
sEdge.setIsclone(true);
}
- Queue<ScheduleNode> toClone = new LinkedList<ScheduleNode>();
- Queue<ScheduleNode> clone = new LinkedList<ScheduleNode>();
- Queue<Hashtable> qcn2cn = new LinkedList<Hashtable>();
+ Queue<ScheduleNode> toClone = new LinkedList<ScheduleNode>(); // all nodes to be cloned
+ Queue<ScheduleNode> clone = new LinkedList<ScheduleNode>(); //clone nodes
+ Queue<Hashtable> qcn2cn = new LinkedList<Hashtable>(); // queue of the mappings of classnodes inside cloned ScheduleNode
+ Vector<ScheduleNode> origins = new Vector<ScheduleNode>(); // queue of source ScheduleNode cloned
+ Hashtable<ScheduleNode, ScheduleNode> sn2sn = new Hashtable<ScheduleNode, ScheduleNode>(); // mapping from cloned ScheduleNode to clone ScheduleNode
clone.add(csNode);
toClone.add((ScheduleNode)sEdge.getTarget());
+ origins.addElement((ScheduleNode)sEdge.getTarget());
+ sn2sn.put((ScheduleNode)sEdge.getTarget(), csNode);
qcn2cn.add(cn2cn);
while(!toClone.isEmpty()) {
Hashtable<ClassNode, ClassNode> tocn2cn = new Hashtable<ClassNode, ClassNode>();
scheduleNodes.add(tSNode);
clone.add(tSNode);
toClone.add((ScheduleNode)tse.getTarget());
+ origins.addElement((ScheduleNode)tse.getTarget());
+ sn2sn.put((ScheduleNode)tse.getTarget(), tSNode);
qcn2cn.add(tocn2cn);
ScheduleEdge se = null;
- if(tse.getIsNew()) {
- se = new ScheduleEdge(tSNode, "new", tse.getFstate(), tse.getIsNew(), 0);//new ScheduleEdge(tSNode, "new", tse.getClassDescriptor(), tse.getIsNew(), 0);
- se.setProbability(tse.getProbability());
- se.setNewRate(tse.getNewRate());
- } else {
- se = new ScheduleEdge(tSNode, "transmit", tse.getFstate(), false, 0);//new ScheduleEdge(tSNode, "transmit", tse.getClassDescriptor(), false, 0);
+ switch(tse.getType()) {
+ case ScheduleEdge.NEWEDGE: {
+ se = new ScheduleEdge(tSNode, "new", tse.getFstate(), tse.getType(), 0);
+ break;
+ }
+ case ScheduleEdge.TRANSEDGE: {
+ se = new ScheduleEdge(tSNode, "transmit", tse.getFstate(), tse.getType(), 0);
+ break;
+ }
+ /*case ScheduleEdge.ASSOCEDGE: {
+ se = new ScheduleEdge(tSNode, "associate", tse.getFstate(), tse.getType(), 0);
+ break;
+ }*/
+ default: {
+ throw new Exception("Error: not valid ScheduleEdge here");
+ }
}
se.setSourceCNode(cn2cn.get(tse.getSourceCNode()));
se.setTargetCNode(tocn2cn.get(tse.getTargetCNode()));
se.setFEdge(tse.getFEdge());
se.setTargetFState(tse.getTargetFState());
+ se.setProbability(tse.getProbability());
+ se.setNewRate(tse.getNewRate());
se.setIsclone(true);
csNode.addEdge(se);
scheduleEdges.add(se);
tocn2cn = null;
edges = null;
}
+
+ // associate ScheduleEdges
+ /*for(int j = 0; j < origins.size(); ++j) {
+ ScheduleNode osNode = origins.elementAt(i);
+ Vector<ScheduleEdge> edges = osNode.getAssociateSEdges();
+ ScheduleNode csNode = sn2sn.get(osNode);
+ for(i = 0; i < edges.size(); i++) {
+ ScheduleEdge tse = (ScheduleEdge)edges.elementAt(i);
+ assert(tse.getType() == ScheduleEdge.ASSOCEDGE);
+ ScheduleNode tSNode = (ScheduleNode)tse.getTarget();
+ if(origins.contains(tSNode)) {
+ tSNode = sn2sn.get(tSNode);
+ }
+ ScheduleEdge se = new ScheduleEdge(tSNode, "associate", tse.getFstate(), tse.getType(), 0);
+ se.setSourceCNode(cn2cn.get(tse.getSourceCNode()));
+ se.setTargetCNode(tocn2cn.get(tse.getTargetCNode()));
+ se.setFEdge(tse.getFEdge());
+ se.setTargetFState(tse.getTargetFState());
+ se.setProbability(tse.getProbability());
+ se.setNewRate(tse.getNewRate());
+ se.setIsclone(true);
+ csNode.addAssociateSEdge(se);
+ }
+ tocn2cn = null;
+ edges = null;
+ }*/
+
toClone = null;
clone = null;
qcn2cn = null;
exeTime = cNode.getFlagStates().elementAt(0).getExeTime() - fs.getExeTime();
while(true) {
Vector inedges = cNode.getInedgeVector();
+ // Now that there are associate ScheduleEdges, there may be multiple inedges of a ClassNode
if(inedges.size() > 1) {
throw new Exception("Error: ClassNode's inedges more than one!");
}
if(inedges.size() > 0) {
+ /*ScheduleEdge sEdge = null;
+ for(int i = 0; i < inedges.size(); ++i) {
+ sEdge = (ScheduleEdge)inedges.elementAt(i);
+ if(sEdge.getType() == ScheduleEdge.NEWEDGE) {
+ break;
+ }
+ }*/
ScheduleEdge sEdge = (ScheduleEdge)inedges.elementAt(0);
cNode = (ClassNode)sEdge.getSource();
exeTime += cNode.getFlagStates().elementAt(0).getExeTime();
}
private ScheduleNode splitSNode(ScheduleEdge se, boolean copy) {
+ assert(ScheduleEdge.NEWEDGE == se.getType());
+
FEdge fe = se.getFEdge();
FlagState fs = (FlagState)fe.getTarget();
FlagState nfs = (FlagState)fs.clone();
toiterate = null;
// create a 'trans' ScheudleEdge between this new ScheduleNode and se's source ScheduleNode
- ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", fs, false, 0);//new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false, 0);
+ ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", fs, ScheduleEdge.TRANSEDGE, 0);//new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false, 0);
sEdge.setFEdge(fe);
sEdge.setSourceCNode(sCNode);
sEdge.setTargetCNode(cNode);
sEdge.setTargetFState(nfs);
- // todo
+ // TODO
// Add calculation codes for calculating transmit time of an object
sEdge.setTransTime(cNode.getTransTime());
se.getSource().addEdge(sEdge);
toremove.clear();
// redirect ScheudleEdges out of this subtree to the new ScheduleNode
Iterator it_sEdges = se.getSource().edges();
- //Vector<ScheduleEdge> toremove = new Vector<ScheduleEdge>();
while(it_sEdges.hasNext()) {
ScheduleEdge tse = (ScheduleEdge)it_sEdges.next();
if((tse != se) && (tse != sEdge) && (tse.getSourceCNode() == sCNode)) {
toremove = null;
sFStates = null;
- if(!copy) {
- //merge se into its source ScheduleNode
- ((ScheduleNode)se.getSource()).mergeSEdge(se);
- scheduleNodes.remove(se.getTarget());
- scheduleEdges.removeElement(se);
- // As se has been changed into an internal edge inside a ScheduleNode,
- // change the source and target of se from original ScheduleNodes into ClassNodes.
- se.setTarget(se.getTargetCNode());
- se.setSource(se.getSourceCNode());
- } else {
- handleScheduleEdge(se, true);
+ try {
+ if(!copy) {
+ //merge se into its source ScheduleNode
+ ((ScheduleNode)se.getSource()).mergeSEdge(se);
+ scheduleNodes.remove(se.getTarget());
+ scheduleEdges.removeElement(se);
+ // As se has been changed into an internal edge inside a ScheduleNode,
+ // change the source and target of se from original ScheduleNodes into ClassNodes.
+ se.setTarget(se.getTargetCNode());
+ se.setSource(se.getSourceCNode());
+ se.getTargetCNode().addEdge(se);
+ } else {
+ handleScheduleEdge(se, true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(-1);
}
return sNode;
// Enough cores, no need to merge more ScheduleEdge
if(!(reduceNum > 0)) {
this.scheduleGraphs.addElement(this.scheduleNodes);
+ int gid = 1;
+ String path = "scheduling_" + gid + ".dot";
+ SchedulingUtil.printScheduleGraph(path, this.scheduleNodes);
} else {
// sort the ScheduleEdges in dececending order of transmittime
Vector<ScheduleEdge> sEdges = new Vector<ScheduleEdge>();
this.schedulings = new Vector<Vector<Schedule>>();
}
+ Vector<TaskDescriptor> multiparamtds = new Vector<TaskDescriptor>();
+ Iterator it_tasks = state.getTaskSymbolTable().getDescriptorsIterator();
+ while(it_tasks.hasNext()) {
+ TaskDescriptor td = (TaskDescriptor)it_tasks.next();
+ if(td.numParameters() > 1) {
+ multiparamtds.addElement(td);
+ }
+ }
+
for(int i = 0; i < this.scheduleGraphs.size(); i++) {
+ Hashtable<TaskDescriptor, Vector<Schedule>> td2cores = new Hashtable<TaskDescriptor, Vector<Schedule>>(); // multiparam tasks reside on which cores
Vector<ScheduleNode> scheduleGraph = this.scheduleGraphs.elementAt(i);
Vector<Schedule> scheduling = new Vector<Schedule>(scheduleGraph.size());
// for each ScheduleNode create a schedule node representing a core
while(it_edges.hasNext()) {
TaskDescriptor td = ((FEdge)it_edges.next()).getTask();
tmpSchedule.addTask(td);
+ if(td.numParameters() > 1) {
+ if(!td2cores.containsKey(td)) {
+ td2cores.put(td, new Vector<Schedule>());
+ }
+ Vector<Schedule> tmpcores = td2cores.get(td);
+ if(!tmpcores.contains(tmpSchedule)) {
+ tmpcores.add(tmpSchedule);
+ }
+ tmpSchedule.addFState4TD(td, fs);
+ }
if(td.getParamType(0).getClassDesc().getSymbol().equals(TypeUtil.StartupClass)) {
assert(!setstartupcore);
startupcore = j;
ScheduleEdge se = (ScheduleEdge)it_edges.next();
ScheduleNode target = (ScheduleNode)se.getTarget();
Integer targetcore = sn2coreNum.get(target);
- if(se.getIsNew()) {
+ switch(se.getType()) {
+ case ScheduleEdge.NEWEDGE: {
for(int k = 0; k < se.getNewRate(); k++) {
tmpSchedule.addTargetCore(se.getFstate(), targetcore);
}
- } else {
+ break;
+ }
+ case ScheduleEdge.TRANSEDGE: {
// 'transmit' edge
tmpSchedule.addTargetCore(se.getFstate(), targetcore, se.getTargetFState());
+ // check if missed some FlagState associated with some multi-parameter
+ // task, which has been cloned when splitting a ClassNode
+ FlagState fs = se.getSourceFState();
+ FlagState tfs = se.getTargetFState();
+ Iterator it = tfs.edges();
+ while(it.hasNext()) {
+ TaskDescriptor td = ((FEdge)it.next()).getTask();
+ if(td.numParameters() > 1) {
+ if(tmpSchedule.getTasks().contains(td)) {
+ tmpSchedule.addFState4TD(td, fs);
+ }
+ }
+ }
+ break;
+ }
+ /*case ScheduleEdge.ASSOCEDGE: {
+ //TODO
+ +
+ }*/
}
tmpSchedule.addChildCores(targetcore);
if((targetcore.intValue() != j) && (!ancestorCores[targetcore.intValue()].contains((Integer.valueOf(j))))) {
it_edges = sn.getScheduleEdgesIterator();
while(it_edges.hasNext()) {
ScheduleEdge se = (ScheduleEdge)it_edges.next();
- if(se.getIsNew()) {
+ switch(se.getType()) {
+ case ScheduleEdge.NEWEDGE: {
for(int k = 0; k < se.getNewRate(); k++) {
tmpSchedule.addTargetCore(se.getFstate(), j);
}
- } else {
+ break;
+ }
+ case ScheduleEdge.TRANSEDGE: {
// 'transmit' edge
tmpSchedule.addTargetCore(se.getFstate(), j, se.getTargetFState());
+ break;
+ }
+ /*case ScheduleEdge.ASSOCEDGE: {
+ //TODO
+ +
+ }*/
}
}
scheduling.add(tmpSchedule);
- }
+ }
+
leafcores.removeElement(Integer.valueOf(startupcore));
ancestorCores[startupcore] = leafcores;
- for(j = 0; j < this.coreNum; ++j) {
+ int number = this.coreNum;
+ if(scheduling.size() < number) {
+ number = scheduling.size();
+ }
+ for(j = 0; j < number; ++j) {
scheduling.elementAt(j).setAncestorCores(ancestorCores[j]);
}
+
+ // set up all the associate ally cores
+ if(multiparamtds.size() > 0) {
+ Object[] tds = (td2cores.keySet().toArray());
+ for(j = 0; j < tds.length; ++j) {
+ TaskDescriptor td = (TaskDescriptor)tds[j];
+ Vector<Schedule> cores = td2cores.get(td);
+ if(cores.size() == 1) {
+ continue;
+ }
+ for(int k = 0; k < cores.size(); ++k) {
+ Schedule tmpSchedule = cores.elementAt(k);
+ Vector<FlagState> tmpfss = tmpSchedule.getFStates4TD(td);
+ for(int h = 0; h < tmpfss.size(); ++h) {
+ for(int l = 0; l < cores.size(); ++l) {
+ if(l != k) {
+ tmpSchedule.addAllyCore(tmpfss.elementAt(h), cores.elementAt(l).getCoreNum());
+ }
+ }
+ }
+ }
+ }
+ }
+
this.schedulings.add(scheduling);
}
ScheduleNode ctarget = sn2sn.get(sse.getTarget());
Hashtable<ClassNode, ClassNode> sourcecn2cn = sn2hash.get(csource);
Hashtable<ClassNode, ClassNode> targetcn2cn = sn2hash.get(ctarget);
- ScheduleEdge se;
- if(sse.getIsNew()) {
- se = new ScheduleEdge(ctarget, "new", sse.getFstate(), sse.getIsNew(), gid);//new ScheduleEdge(ctarget, "new", sse.getClassDescriptor(), sse.getIsNew(), gid);
+ ScheduleEdge se = null;
+ switch(sse.getType()) {
+ case ScheduleEdge.NEWEDGE: {
+ se = new ScheduleEdge(ctarget, "new", sse.getFstate(), sse.getType(), gid);//new ScheduleEdge(ctarget, "new", sse.getClassDescriptor(), sse.getIsNew(), gid);
se.setProbability(sse.getProbability());
se.setNewRate(sse.getNewRate());
- } else {
- se = new ScheduleEdge(ctarget, "transmit", sse.getFstate(), false, gid);//new ScheduleEdge(ctarget, "transmit", sse.getClassDescriptor(), false, gid);
+ break;
+ }
+ case ScheduleEdge.TRANSEDGE: {
+ se = new ScheduleEdge(ctarget, "transmit", sse.getFstate(), sse.getType(), gid);//new ScheduleEdge(ctarget, "transmit", sse.getClassDescriptor(), false, gid);
+ break;
+ }
+ /*case ScheduleEdge.ASSOCEDGE: {
+ //TODO
+ se = new ScheduleEdge(ctarget, "associate", sse.getFstate(), sse.getType(), gid);//new ScheduleEdge(ctarget, "transmit", sse.getClassDescriptor(), false, gid);
+ break;
+ }*/
}
se.setSourceCNode(sourcecn2cn.get(sse.getSourceCNode()));
se.setTargetCNode(targetcn2cn.get(sse.getTargetCNode()));
for(int i = 0; i < toMerge.size(); i++) {
ScheduleEdge sEdge = toMerge.elementAt(i);
// merge this edge
- if(sEdge.getIsNew()) {
- ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
- } else {
+ switch(sEdge.getType()) {
+ case ScheduleEdge.NEWEDGE: {
try {
- ((ScheduleNode)sEdge.getSource()).mergeTransEdge(sEdge);
+ ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
} catch(Exception e) {
e.printStackTrace();
System.exit(-1);
}
+ break;
+ }
+ case ScheduleEdge.TRANSEDGE: {
+ try {
+ ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
+ } catch(Exception e) {
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ break;
+ }
+ /*case ScheduleEdge.ASSOCEDGE: {
+ // TODO
+ +
+ }*/
}
result.removeElement(sEdge.getTarget());
- if(sEdge.getIsNew()) {
+ if(ScheduleEdge.NEWEDGE == sEdge.getType()) {
// As se has been changed into an internal edge inside a ScheduleNode,
// change the source and target of se from original ScheduleNodes into ClassNodes.
sEdge.setTarget(sEdge.getTargetCNode());
sEdge.setSource(sEdge.getSourceCNode());
+ sEdge.getTargetCNode().addEdge(sEdge);
}
}
toMerge = null;
import java.util.Iterator;
-import IR.*;
import Analysis.TaskStateAnalysis.*;
import Util.Edge;
import Util.GraphNode;
/* Edge *****************/
-
public class ScheduleEdge extends Edge {
-
- private int uid;
- private int gid;
- private static int nodeID=0;
-
- private String label;
- //private final ClassDescriptor cd;
- private final FlagState fstate;
- private boolean isNew = true;
-
- private FlagState targetFState;
+
+ public final static int NEWEDGE = 0;
+ public final static int TRANSEDGE = 1;
+ public final static int ASSOCEDGE = 2;
+
+ protected int uid;
+ protected int gid;
+ protected static int nodeID=0;
+
+ protected String label;
+ protected final FlagState fstate;
+ protected int type; // 0--new edge: indicate creating new objects
+ // 1--transmit edge: indicate transimitting an existing object
+ // 2-- associate edge: indicate association with another object in that they are both parameters of one task
+
+ protected FlagState targetFState; // associate edge's targetFState is always null
+
private ClassNode sourceCNode;
private ClassNode targetCNode;
-
+
private int probability;
private int transTime;
private int listExeTime;
-
+
private FEdge fedge;
private int newRate;
-
+
private boolean isclone;
-
+
/** Class Constructor
*
*/
- public ScheduleEdge(ScheduleNode target, String label, /*ClassDescriptor cd,*/FlagState fstate, int gid) {
- super(target);
- this.uid = ScheduleEdge.nodeID++;
- this.gid = gid;
- this.fedge = null;
- this.targetFState = null;
- this.sourceCNode = null;
- this.targetCNode = null;
- this.label = label;
- //this.cd = cd;
- this.fstate = fstate;
- this.newRate = -1;
- this.probability = 100;
- this.transTime = -1;
- this.listExeTime = -1;
- this.isclone = false;
- }
-
- public ScheduleEdge(ScheduleNode target, String label, /*ClassDescriptor cd,*/FlagState fstate, boolean isNew, int gid) {
- super(target);
- this.uid = ScheduleEdge.nodeID++;
- this.gid = gid;
- this.fedge = null;
- this.targetFState = null;
- this.sourceCNode = null;
- this.targetCNode = null;
- this.label = label;
- //this.cd = cd;
- this.fstate = fstate;
- this.newRate = -1;
- this.probability = 100;
- this.transTime = -1;
- this.listExeTime = -1;
- this.isNew = isNew;
- this.isclone = false;
- }
-
- public boolean isclone() {
- return isclone;
- }
-
- public void setIsclone(boolean isclone) {
- this.isclone = isclone;
- }
-
- public void setTarget(GraphNode sn) {
- this.target = sn;
- }
-
- public String getLabel() {
- String completeLabel = label;
- if(isNew) {
- completeLabel += ":" + Integer.toString(this.newRate);
- }
- completeLabel += ":(" + Integer.toString(this.probability) + "%)" + ":[" + Integer.toString(this.transTime) + "]";
- return completeLabel;
- }
-
- /*public ClassDescriptor getClassDescriptor() {
- return cd;
- }*/
-
- public FlagState getFstate() {
- return fstate;
- }
-
- public boolean getIsNew() {
- return this.isNew;
- }
-
- public FEdge getFEdge() {
- return this.fedge;
- }
-
- public void setFEdge(FEdge fEdge) {
- this.fedge = fEdge;
- }
-
- public FlagState getSourceFState() {
- if(this.fedge == null) {
- return null;
- }
- return (FlagState)this.fedge.getTarget();
- }
-
- public void setTargetFState(FlagState targetFState) {
- this.targetFState = targetFState;
- }
-
- public FlagState getTargetFState() {
- return this.targetFState;
- }
-
- public int getProbability() {
- return this.probability;
- }
-
- public int getNewRate() {
- return this.newRate;
- }
-
- public ClassNode getSourceCNode() {
- return this.sourceCNode;
- }
-
- public void setSourceCNode(ClassNode sourceCNode) {
- this.sourceCNode = sourceCNode;
- }
-
- public ClassNode getTargetCNode() {
- return this.targetCNode;
- }
-
- public void setTargetCNode(ClassNode targetCNode) {
- this.targetCNode = targetCNode;
- this.transTime = targetCNode.getTransTime();
- }
-
- public boolean equals(Object o) {
- if (o instanceof ScheduleEdge) {
- ScheduleEdge e=(ScheduleEdge)o;
- if(e.gid == this.gid) {
- if(e.uid != this.uid) {
- return false;
- }
- }
- if ((e.label.equals(label))&&
- (e.target.equals(target))&&
- (e.source.equals(source)) &&
- //(e.cd.equals(cd)) &&
- (e.fstate.equals(fstate)) &&
- (e.sourceCNode.equals(sourceCNode)) &&
- (e.targetCNode.equals(targetCNode)) &&
- (e.newRate == newRate) &&
- (e.probability == probability) &&
- (e.isNew == isNew) &&
- (e.transTime == transTime) &&
- (e.listExeTime == listExeTime))
- if(e.targetFState != null) {
- if(!e.targetFState.equals(targetFState)) {
- return false;
- }
- } else if(this.targetFState != null) {
- return false;
- }
- if(e.fedge != null) {
- return e.fedge.equals(fedge);
- } else if(this.fedge == null) {
- return true;
- }
- }
- return false;
- }
-
- public int hashCode(){
- int hashcode = gid^uid^label.hashCode()^target.hashCode()^source.hashCode()^fstate.hashCode()^//cd.hashCode()^
- sourceCNode.hashCode()^targetCNode.hashCode()^newRate^probability^
- Boolean.toString(isNew).hashCode()^transTime^listExeTime;
- if(targetFState != null) {
- hashcode ^= targetFState.hashCode();
- }
- if(fedge != null) {
- hashcode ^= fedge.hashCode();
- }
- return hashcode;
- }
-
- public void setProbability(int prob) {
- this.probability = prob;
- }
-
- public void setNewRate(int nr) {
- this.newRate = nr;
- }
-
- public int getTransTime() {
- return this.transTime;
- }
-
- public void setTransTime(int transTime) {
- this.transTime = transTime;
- }
-
- public int getListExeTime() {
- if(listExeTime == -1) {
- // calculate the lisExeTime
- listExeTime = ((ScheduleNode)this.getTarget()).getExeTime() + this.getTransTime() * this.getNewRate();
- Iterator it_edges = this.getTarget().edges();
- int temp = 0;
- if(it_edges.hasNext()) {
- temp = ((ScheduleEdge)it_edges.next()).getListExeTime();
- }
- while(it_edges.hasNext()) {
- int tetime = ((ScheduleEdge)it_edges.next()).getListExeTime();
- if(temp < tetime) {
- temp = tetime;
- }
- }
- listExeTime += temp;
- }
- return this.listExeTime;
- }
-
- public void resetListExeTime() {
- this.listExeTime = -1;
- }
+ public ScheduleEdge(ScheduleNode target, String label, FlagState fstate, int type, int gid) {
+ super(target);
+ this.uid = ScheduleEdge.nodeID++;
+ this.gid = gid;
+ this.fedge = null;
+ this.targetFState = null;
+ this.sourceCNode = null;
+ this.targetCNode = null;
+ this.label = label;
+ this.fstate = fstate;
+ this.newRate = -1;
+ this.probability = 100;
+ this.transTime = -1;
+ this.listExeTime = -1;
+ this.isclone = false;
+ this.type = type;
+ }
+
+ public boolean isclone() {
+ return isclone;
+ }
+
+ public void setIsclone(boolean isclone) {
+ this.isclone = isclone;
+ }
+
+ public void setTarget(GraphNode sn) {
+ this.target = sn;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public String getLabel() {
+ String completeLabel = label;
+ if(ScheduleEdge.NEWEDGE == this.type) {
+ completeLabel += ":" + Integer.toString(this.newRate);
+ }
+ completeLabel += ":(" + Integer.toString(this.probability) + "%)" + ":[" + Integer.toString(this.transTime) + "]";
+ return completeLabel;
+ }
+
+ public FlagState getFstate() {
+ return fstate;
+ }
+
+ public FEdge getFEdge() {
+ return this.fedge;
+ }
+
+ public void setFEdge(FEdge fEdge) {
+ this.fedge = fEdge;
+ }
+
+ public FlagState getSourceFState() {
+ if(this.fedge == null) {
+ return null;
+ }
+ return (FlagState)this.fedge.getTarget();
+ }
+
+ public void setTargetFState(FlagState targetFState) {
+ this.targetFState = targetFState;
+ }
+
+ public FlagState getTargetFState() {
+ return this.targetFState;
+ }
+
+ public int getProbability() {
+ return this.probability;
+ }
+
+ public int getNewRate() {
+ return this.newRate;
+ }
+
+ public ClassNode getSourceCNode() {
+ return this.sourceCNode;
+ }
+
+ public void setSourceCNode(ClassNode sourceCNode) {
+ this.sourceCNode = sourceCNode;
+ }
+
+ public ClassNode getTargetCNode() {
+ return this.targetCNode;
+ }
+
+ public void setTargetCNode(ClassNode targetCNode) {
+ this.targetCNode = targetCNode;
+ //this.targetCNode.getInedgeVector().addElement(this);
+ this.transTime = targetCNode.getTransTime();
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof ScheduleEdge) {
+ ScheduleEdge e=(ScheduleEdge)o;
+ if(e.gid == this.gid) {
+ if(e.uid != this.uid) {
+ return false;
+ }
+ }
+ if ((e.label.equals(label))&&
+ (e.target.equals(target))&&
+ (e.source.equals(source)) &&
+ (e.fstate.equals(fstate)) &&
+ (e.sourceCNode.equals(sourceCNode)) &&
+ (e.targetCNode.equals(targetCNode)) &&
+ (e.newRate == newRate) &&
+ (e.probability == probability) &&
+ (e.type == type) &&
+ (e.transTime == transTime) &&
+ (e.listExeTime == listExeTime))
+ if(e.targetFState != null) {
+ if(!e.targetFState.equals(targetFState)) {
+ return false;
+ }
+ } else if(this.targetFState != null) {
+ return false;
+ }
+ if(e.fedge != null) {
+ return e.fedge.equals(fedge);
+ } else if(this.fedge == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public int hashCode(){
+ int hashcode = gid^uid^label.hashCode()^target.hashCode()^source.hashCode()^fstate.hashCode()^
+ sourceCNode.hashCode()^targetCNode.hashCode()^newRate^probability^
+ type^transTime^listExeTime;
+ if(targetFState != null) {
+ hashcode ^= targetFState.hashCode();
+ }
+ if(fedge != null) {
+ hashcode ^= fedge.hashCode();
+ }
+ return hashcode;
+ }
+
+ public void setProbability(int prob) {
+ this.probability = prob;
+ }
+
+ public void setNewRate(int nr) {
+ this.newRate = nr;
+ }
+
+ public int getTransTime() {
+ return this.transTime;
+ }
+
+ public void setTransTime(int transTime) {
+ this.transTime = transTime;
+ }
+
+ public int getListExeTime() {
+ if(listExeTime == -1) {
+ // calculate the lisExeTime
+ listExeTime = ((ScheduleNode)this.getTarget()).getExeTime() + this.getTransTime() * this.getNewRate();
+ Iterator it_edges = this.getTarget().edges();
+ int temp = 0;
+ if(it_edges.hasNext()) {
+ temp = ((ScheduleEdge)it_edges.next()).getListExeTime();
+ }
+ while(it_edges.hasNext()) {
+ int tetime = ((ScheduleEdge)it_edges.next()).getListExeTime();
+ if(temp < tetime) {
+ temp = tetime;
+ }
+ }
+ listExeTime += temp;
+ }
+ return this.listExeTime;
+ }
+
+ public void resetListExeTime() {
+ this.listExeTime = -1;
+ }
}
private Vector<ClassNode> classNodes;
Vector<ScheduleEdge> scheduleEdges;
+ private Vector<ScheduleEdge> associateEdges;
+ private Vector<ScheduleEdge> inassociateEdges;
private int executionTime;
this.executionTime = -1;
this.classNodes = null;
this.scheduleEdges = null;
+ this.associateEdges = new Vector<ScheduleEdge>();
+ this.inassociateEdges = new Vector<ScheduleEdge>();
}
public ScheduleNode(ClassNode cn, int gid) {
this.classNodes.add(cn);
this.addEdge(cn.getEdgeVector());
this.executionTime = -1;
+ this.associateEdges = new Vector<ScheduleEdge>();
+ this.inassociateEdges = new Vector<ScheduleEdge>();
}
public int getuid() {
scheduleEdges = null;
}
+ public Vector getAssociateSEdges() {
+ return this.associateEdges;
+ }
+
+ public Iterator getAssociateSEdgesIterator() {
+ return this.associateEdges.iterator();
+ }
+
+ public void addAssociateSEdge(ScheduleEdge se) {
+ assert(ScheduleEdge.ASSOCEDGE == se.getType());
+
+ this.associateEdges.addElement(se);
+ se.setSource(this);
+ ScheduleNode tonode=(ScheduleNode)se.getTarget();
+ tonode.addInAssociateSEdge(se);
+ }
+
+ public Vector getInAssociateSEdges() {
+ return this.inassociateEdges;
+ }
+
+ public Iterator getInAssociateSEdgesIterator() {
+ return this.inassociateEdges.iterator();
+ }
+
+ public void addInAssociateSEdge(ScheduleEdge se) {
+ assert(ScheduleEdge.ASSOCEDGE == se.getType());
+
+ this.inassociateEdges.addElement(se);
+ }
+
public int getExeTime() {
if(this.executionTime == -1) {
try {
for(i = 0; i < this.scheduleEdges.size(); i++) {
ScheduleEdge temp = this.scheduleEdges.elementAt(i);
ScheduleEdge se = null;
- if(!temp.getIsNew()) {
- se = new ScheduleEdge(o, "transmit",temp.getFstate(), false, gid);//new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false, gid);
- } else {
- se = new ScheduleEdge(o, "new",temp.getFstate(), gid);//new ScheduleEdge(o, "new",temp.getClassDescriptor(), gid);
+ switch(temp.getType()) {
+ case ScheduleEdge.NEWEDGE: {
+ se = new ScheduleEdge(o, "new", temp.getFstate(), ScheduleEdge.NEWEDGE, gid);
+ se.setProbability(temp.getProbability());
+ se.setNewRate(temp.getNewRate());
+ break;
+ }
+ case ScheduleEdge.TRANSEDGE: {
+ se = new ScheduleEdge(o, "transmit", temp.getFstate(), ScheduleEdge.TRANSEDGE, gid);
+ se.setProbability(temp.getProbability());
+ se.setNewRate(temp.getNewRate());
+ break;
+ }
+ case ScheduleEdge.ASSOCEDGE: {
+ //TODO
+ se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
+ break;
+ }
}
se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
- se.setProbability(temp.getProbability());
- se.setNewRate(temp.getNewRate());
se.setTransTime(temp.getTransTime());
se.setFEdge(temp.getFEdge());
se.setTargetFState(temp.getTargetFState());
o.scheduleEdges = tses;
tcns = null;
tses = null;
- o.inedges = new Vector();
- o.edges = new Vector();
-
- return o;
- }
-
- public void mergeSEdge(ScheduleEdge se) {
- assert(se.getIsNew());
-
- Vector<ClassNode> targetCNodes = (Vector<ClassNode>)((ScheduleNode)se.getTarget()).getClassNodes();
- Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)((ScheduleNode)se.getTarget()).getScheduleEdges();
- for(int i = 0; i < targetCNodes.size(); i++) {
- targetCNodes.elementAt(i).setScheduleNode(this);
+ /*Vector<ScheduleEdge> assses = new Vector<ScheduleEdge>();
+ for(i = 0; i < this.scheduleEdges.size(); i++) {
+ ScheduleEdge temp = this.scheduleEdges.elementAt(i);
+
+ assert(ScheduleEdge.ASSOCEDGE == temp.getType());
+ ScheduleEdge se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
+ se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
+ se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
+ se.setTransTime(temp.getTransTime());
+ se.setFEdge(temp.getFEdge());
+ se.setTargetFState(temp.getTargetFState());
+ se.setIsclone(true);
+ assses.add(se);
}
+ o.associateEdges = assses;
+ assses = null;
- if(classNodes == null) {
- classNodes = targetCNodes;
- scheduleEdges = targetSEdges;
- } else {
- if(targetCNodes.size() != 0) {
- classNodes.addAll(targetCNodes);
- }
- if(targetSEdges.size() != 0) {
- scheduleEdges.addAll(targetSEdges);
- }
+ Vector<ScheduleEdge> assses = new Vector<ScheduleEdge>();
+ for(i = 0; i < this.scheduleEdges.size(); i++) {
+ ScheduleEdge temp = this.scheduleEdges.elementAt(i);
+
+ assert(ScheduleEdge.ASSOCEDGE == temp.getType());
+ ScheduleEdge se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
+ se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
+ se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
+ se.setTransTime(temp.getTransTime());
+ se.setFEdge(temp.getFEdge());
+ se.setTargetFState(temp.getTargetFState());
+ se.setIsclone(true);
+ assses.add(se);
}
- targetCNodes = null;
- targetSEdges = null;
-
- scheduleEdges.add(se);
- se.resetListExeTime();
- se.getTarget().removeInedge(se);
- this.removeEdge(se);
- Iterator it_edges = se.getTarget().edges();
- while(it_edges.hasNext()) {
- ScheduleEdge tse = (ScheduleEdge)it_edges.next();
- tse.setSource(this);
- this.edges.addElement(tse);
- }
+ o.associateEdges = assses;
+ assses = null;*/
- // As all tasks inside one ScheduleNode are executed sequentially,
- // simply add the execution time of all the ClassNodes inside one ScheduleNode.
- if(this.executionTime == -1) {
- this.executionTime = 0;
- }
- this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
+ o.inedges = new Vector();
+ o.edges = new Vector();
+ o.associateEdges = new Vector<ScheduleEdge>();
+ o.inassociateEdges = new Vector<ScheduleEdge>();
+ return o;
}
- public void mergeTransEdge(ScheduleEdge se) throws Exception {
+ public void mergeSEdge(ScheduleEdge se) throws Exception {
ScheduleNode sn = (ScheduleNode)se.getTarget();
Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
}
}
targetCNodes = null;
+
+ if(ScheduleEdge.TRANSEDGE == se.getType()) {
+ sn.removeInedge(se);
+ this.removeEdge(se);
+ Iterator it_edges = sn.edges();
+ while(it_edges.hasNext()) {
+ ScheduleEdge tse = (ScheduleEdge)it_edges.next();
+ tse.setSource(this);
+ this.edges.addElement(tse);
+ }
- sn.removeInedge(se);
- this.removeEdge(se);
- Iterator it_edges = sn.edges();
- while(it_edges.hasNext()) {
- ScheduleEdge tse = (ScheduleEdge)it_edges.next();
- tse.setSource(this);
- this.edges.addElement(tse);
- }
+ // merge the split ClassNode of same class
+ FlagState sfs = se.getFstate();
+ FlagState tfs = se.getTargetFState();
+ ClassNode scn = se.getSourceCNode();
+ ClassNode tcn = se.getTargetCNode();
+ sfs.getEdgeVector().addAll(tfs.getEdgeVector());
+ // merge the subtree whose root is nfs from the whole flag transition tree
+ Vector<FlagState> sfss = scn.getFlagStates();
+ sfss.addAll(tcn.getFlagStates());
+ sfss.removeElement(tfs);
+ classNodes.removeElement(tcn);
+
+ // flush the exeTime of fs and its ancestors
+ sfs.setExeTime(0);
+ Queue<FlagState> toiterate = new LinkedList<FlagState>();
+ toiterate.add(sfs);
+ while(!toiterate.isEmpty()) {
+ FlagState tmpfs = toiterate.poll();
+ int ttime = tmpfs.getExeTime();
+ Iterator it_inedges = tmpfs.inedges();
+ while(it_inedges.hasNext()) {
+ FEdge fEdge = (FEdge)it_inedges.next();
+ FlagState temp = (FlagState)fEdge.getSource();
+ int time = fEdge.getExeTime() + ttime;
+ if(temp.getExeTime() > time) {
+ temp.setExeTime(time);
+ toiterate.add(temp);
+ }
+ }
+ }
+ toiterate = null;
+
+ // redirct internal ScheduleEdge from tcn to scn
+ for(int i = 0; i < targetSEdges.size(); ++i) {
+ ScheduleEdge tmpse = targetSEdges.elementAt(i);
+ if(tmpse.getSourceCNode().equals(tcn)) {
+ tmpse.setSourceCNode(scn);
+ }
+ }
+
+ targetSEdges = null;
+
+ // As all tasks inside one ScheduleNode are executed sequentially,
+ // simply add the execution time of all the ClassNodes inside one ScheduleNode.
+ if(this.executionTime == -1) {
+ throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
+ }
+ if(this.executionTime < sn.getExeTime()) {
+ this.executionTime = sn.getExeTime();
+ }
+ } else if(ScheduleEdge.NEWEDGE == se.getType()) {
+ targetSEdges = null;
- // merge the split ClassNode of same class
- FlagState sfs = se.getFstate();
- FlagState tfs = se.getTargetFState();
- ClassNode scn = se.getSourceCNode();
- ClassNode tcn = se.getTargetCNode();
- sfs.getEdgeVector().addAll(tfs.getEdgeVector());
- // merge the subtree whose root is nfs from the whole flag transition tree
- Vector<FlagState> sfss = scn.getFlagStates();
- sfss.addAll(tcn.getFlagStates());
- sfss.removeElement(tfs);
- classNodes.removeElement(tcn);
-
- // flush the exeTime of fs and its ancestors
- sfs.setExeTime(0);
- Queue<FlagState> toiterate = new LinkedList<FlagState>();
- toiterate.add(sfs);
- while(!toiterate.isEmpty()) {
- FlagState tmpfs = toiterate.poll();
- int ttime = tmpfs.getExeTime();
- Iterator it_inedges = tmpfs.inedges();
- while(it_inedges.hasNext()) {
- FEdge fEdge = (FEdge)it_inedges.next();
- FlagState temp = (FlagState)fEdge.getSource();
- int time = fEdge.getExeTime() + ttime;
- if(temp.getExeTime() > time) {
- temp.setExeTime(time);
- toiterate.add(temp);
- }
- }
- }
- toiterate = null;
-
- // redirct internal ScheduleEdge from tcn to scn
- for(int i = 0; i < targetSEdges.size(); ++i) {
- ScheduleEdge tmpse = targetSEdges.elementAt(i);
- if(tmpse.getSourceCNode().equals(tcn)) {
- tmpse.setSourceCNode(scn);
- }
- }
- targetSEdges = null;
-
- // As all tasks inside one ScheduleNode are executed sequentially,
- // simply add the execution time of all the ClassNodes inside one ScheduleNode.
- if(this.executionTime == -1) {
- throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
- }
- if(this.executionTime < sn.getExeTime()) {
- this.executionTime = sn.getExeTime();
+ scheduleEdges.add(se);
+ se.resetListExeTime();
+ sn.removeInedge(se);
+ this.removeEdge(se);
+ Iterator it_edges = sn.edges();
+ while(it_edges.hasNext()) {
+ ScheduleEdge tse = (ScheduleEdge)it_edges.next();
+ tse.setSource(this);
+ this.edges.addElement(tse);
+ }
+
+ // As all tasks inside one ScheduleNode are executed sequentially,
+ // simply add the execution time of all the ClassNodes inside one ScheduleNode.
+ if(this.executionTime == -1) {
+ this.executionTime = 0;
+ }
+ this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
}
}
}
package Analysis.TaskStateAnalysis;
+import Analysis.Scheduling.ScheduleEdge;
import Analysis.TaskStateAnalysis.*;
import IR.*;
import IR.Tree.*;
public static final int KLIMIT=2;
// jzhou
+ // for static scheduling
private int executeTime;
private int invokeNum;
// for building multicore codes
private int checkmask;
private boolean setmask;
private int iuid;
+ //private boolean isolate;
+ //private Vector<ScheduleEdge> allys;
/** Class constructor
* Creates a new flagstate with all flags set to false.
this.checkmask = 0;
this.setmask = false;
this.iuid = 0;
+ //this.isolate = true;
+ //this.allys = null;
}
/** Class constructor
return next;
}
+
+ /*public Vector<ScheduleEdge> getAllys() {
+ return allys;
+ }
+
+ public void addAlly(ScheduleEdge se) {
+ if(this.allys == null) {
+ assert(this.isolate == true);
+ this.isolate = false;
+ this.allys = new Vector<ScheduleEdge>();
+ }
+ this.allys.addElement(se);
+ }
+
+ public boolean isIsolate() {
+ return isolate;
+ }*/
+
}
import IR.*;
import java.util.*;
import java.io.*;
+
import Util.Relation;
import Analysis.TaskStateAnalysis.FlagState;
import Analysis.TaskStateAnalysis.FlagComparator;
outclassdefs.println(" int flag;");
if(!state.MULTICORE) {
outclassdefs.println(" void * flagptr;");
- } /*else {
- outclassdefs.println(" int corenum;");
- outclassdefs.println(" int flagptr;");
- }*/
+ } else {
+ outclassdefs.println(" int isolate;"); // indicate if this object is shared or not
+ outclassdefs.println(" int version;");
+ outclassdefs.println(" struct ___Object___ * original;");
+ }
if(state.OPTIONAL){
outclassdefs.println(" int numfses;");
outclassdefs.println(" int * fses;");
classdefout.println(" int flag;");
if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
classdefout.println(" void * flagptr;");
- } /*else {
- classdefout.println(" int flagptr;");
- }*/
+ } else if (state.MULTICORE){
+ classdefout.println(" int isolate;"); // indicate if this object is shared or not
+ classdefout.println(" int version;");
+ classdefout.println(" struct ___Object___ * original;");
+ }
if (state.OPTIONAL){
classdefout.println(" int numfses;");
classdefout.println(" int * fses;");
output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
}
}
+ if(state.MULTICORE) {
+ output.println(" " + generateTemp(fm,fn.getDst(),lb)+"->isolate = 1;");
+ output.println(" " + generateTemp(fm,fn.getDst(),lb)+"->version = 0;");
+ }
if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
String revertptr=generateTemp(fm, reverttable.get(lb),lb);
output.println("trans->revertlist="+revertptr+";");
output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
}
- private void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
+ protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
if (frn.getReturnTemp()!=null) {
if (frn.getReturnTemp().getType().isPtr())
output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
else
output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
- } else
+ } else {
output.println("return;");
+ }
}
//private void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
return l;
}
+
+ protected void outputTransCode(PrintWriter output) {
+ }
}
this.currentSchedule = null;
this.fsate2qnames = null;
this.startupcorenum = 0;
+
+ // sometimes there are extra cores then needed in scheduling
+ // TODO
+ // currently, it is guaranteed that in scheduling, the corenum
+ // is started from 0 and continuous.
+ // MAY need modification here in the future when take hardware
+ // information into account.
+ if(this.scheduling.size() < this.coreNum) {
+ this.coreNum = this.scheduling.size();
+ }
}
public void buildCode() {
outtask.println("#define _TASK_H");
outtask.println("#include \"ObjectHash.h\"");
outtask.println("#include \"structdefs.h\"");
+ outtask.println("#include \"Queue.h\"");
outtask.println();
outtask.println("struct tagobjectiterator {");
outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
TempDescriptor temp = fm.getParameter(i);
output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
"->flag;");
+ output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
}
/* Assign labels to FlatNode's if necessary.*/
else
output.println("checkcollect(&"+localsprefix+");");
}*/
+
+ /* Create queues to store objects need to be transferred to other cores and their destination*/
+ output.println(" struct Queue * totransobjqueue = createQueue();");
+ output.println(" struct Queue * desqueue = createQueue();");
+ output.println("int tmpint = 0;");
/* Do the actual code generation */
FlatNode current_node=null;
output.print(" ");
super.generateFlatNode(fm, lb, current_node, output);
if (current_node.kind()!=FKind.FlatReturnNode) {
+ outputTransCode(output);
output.println(" return;");
}
current_node=null;
current_node=current_node.getNext(0);
} else throw new Error();
}
+
output.println("}\n\n");
}
for(int i=0;i<fm.numTags();i++) {
TempDescriptor temp=fm.getTag(i);
int offset=i+objectparams.numPrimitives();
- output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
+ output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];");// add i to fix bugs of duplicate definition of tags
}
if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
Vector<FlagState> initfstates = ffan.getInitFStates(cd);
for(int i = 0; i < initfstates.size(); ++i) {
FlagState tmpFState = initfstates.elementAt(i);
- QueueInfo qinfo = outputqueues(tmpFState, num, output);
+
+ QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
", " + qinfo.length + ");");
}
}
}
+ boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
+ // reside on multiple cores
if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
// ServerSocket object will always reside on current core
for(int j = 0; j < targetFStates.length; ++j) {
if(initfstates != null) {
FlagState fs = initfstates.elementAt(j);
+ //isolate = this.currentSchedule.getAllyCoreTable().keySet().contains(fs);
output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
+ ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
}
Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
for(int i = 0; i < tmpfstates.size(); ++i) {
FlagState tmpFState = tmpfstates.elementAt(i);
+ // TODO
+ // may have bugs here
output.println("/* reside on this core*");
- output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", objq4socketobj[corenum], numqueues4socketobj[corenum]);");
+ output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+ //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", objq4socketobj[corenum], numqueues4socketobj[corenum]);");
//output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
}
if(initfstates != null) {
int num = this.currentSchedule.getCoreNum();
Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
for(int j = 0; j < targetFStates.length; ++j) {
+ FlagState fs = null;
if(initfstates != null) {
- FlagState fs = initfstates.elementAt(j);
+ fs = initfstates.elementAt(j);
output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
+ "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
}
Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
for(int i = 0; i < tmpfstates.size(); ++i) {
FlagState tmpFState = tmpfstates.elementAt(i);
+
+ if(this.currentSchedule.getAllyCoreTable() == null) {
+ isolate = true;
+ } else {
+ isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
+ (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
+ }
+ /*if(isolate) {
+ output.println(super.generateTemp(fm, temp, lb) + "->isolate = 1;"); // not shared object
+ } else {*/
+ if(!isolate) {
+ // indentify this object as a shared object
+ // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
+ // is shared, it maybe shared all the time afterwards
+ output.println(super.generateTemp(fm, temp, lb) + "->isolate = 0;");
+ output.println(super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
+ }
+
+ Vector<Integer> sendto = new Vector<Integer>();
Queue<Integer> queue = null;
if(targetCoreTbl != null) {
queue = targetCoreTbl.get(tmpFState);
targetcore = (Integer)cores[k];
if(targetcore.intValue() == num) {
output.println("/* reside on this core*/");
- QueueInfo qinfo = outputqueues(tmpFState, num, output);
- output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
- ", " + qinfo.length + ");");
+ if(isolate) {
+ QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
+ output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
+ ", " + qinfo.length + ");");
+ } else {
+ output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+ }
//output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
} else {
+ if(!isolate) {
+ output.println("/* possibly needed by multi-parameter tasks on this core*/");
+ output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+ }
output.println("/* transfer to core " + targetcore.toString() + "*/");
// method call of transfer objects
- output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+ //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+ // enqueue this object and its destination
+ output.println(";");
+ output.println("tmpint = "+targetcore.toString()+";");
+ output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
+ output.println("addNewItem(desqueue, (void *)tmpint);");
+ sendto.add(targetcore);
//output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() +
// ", \"" + targetcore.toString() + "\"" + ");");
}
}
output.println("}");
} else {
+ if(!isolate) {
+ output.println("/* possibly needed by multi-parameter tasks on this core*/");
+ output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+ }
output.println("/* transfer to core " + targetcore.toString() + "*/");
// method call of transfer objectts
- output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+ //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+ // enqueue this object and its destination
+ output.println(";");
+ output.println("tmpint = "+targetcore.toString()+";");
+ output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
+ output.println("addNewItem(desqueue, (void *)tmpint);");
+ sendto.add(targetcore);
//output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() +
// ", \"" + targetcore.toString() + "\"" + ");");
}
} else {
// this object will reside on current core
output.println("/* reside on this core*/");
- QueueInfo qinfo = outputqueues(tmpFState, num, output);
- output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
- ", " + qinfo.length + ");");
+ if(isolate) {
+ QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
+ output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
+ ", " + qinfo.length + ");");
+ } else {
+ output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+ }
//output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
}
+
+ // codes for multi-params tasks
+ if(!isolate) {
+ // flagstate associated with some multi-params tasks
+ // need to be send to other cores
+ Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
+ output.println("/* send the shared object to possible queues on other cores*/");
+ for(int k = 0; k < targetcores.size(); ++k) {
+ //QueueInfo qinfo = outputqueues(tmpFState, num, output);
+ // TODO
+ // add the information of exactly which queue
+ if(!sendto.contains(targetcores.elementAt(i))) {
+ // previously not sended to this target core
+ //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcores.elementAt(i).toString() + ");");
+ // enqueue this object and its destination
+ output.println(";");
+ output.println("tmpint = "+targetcores.elementAt(i).toString()+";");
+ output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
+ output.println("addNewItem(desqueue, (void *)tmpint);");
+ }
+ }
+ }
}
+
if(initfstates != null) {
output.println("}");
}
}
}
- private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output) {
+ private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output, boolean isEnqueue) {
// queue array
QueueInfo qinfo = new QueueInfo();
output.println(";");
qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
Iterator it_edges = tmpFState.getEdgeVector().iterator();
+ Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
Vector<Integer> indexes = new Vector<Integer>();
boolean comma = false;
FEdge fe = (FEdge)it_edges.next();
TaskDescriptor td = fe.getTask();
int paraindex = fe.getIndex();
- if((!tasks.contains(td)) ||
- ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
- tasks.addElement(td);
- indexes.addElement(paraindex);
- if(comma) {
- output.println(",");
- } else {
- comma = true;
+ if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
+ if((!tasks.contains(td)) ||
+ ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
+ tasks.addElement(td);
+ indexes.addElement(paraindex);
+ if(comma) {
+ output.println(",");
+ } else {
+ comma = true;
+ }
+ output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
+ ++qinfo.length;
}
- output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
- ++qinfo.length;
}
}
output.println("};");
}
throw new Error();
}
+
+ protected void outputTransCode(PrintWriter output) {
+ output.println("while(0 == isEmpty(totransobjqueue)) {");
+ output.println(" struct QueueItem * totransitem = getTail(totransobjqueue);");
+ output.println(" struct QueueItem * desitem = getTail(desqueue);");
+ output.println(" transferObject(totransitem->objectptr, (int)desitem->objectptr);");
+ output.println(" removeItem(totransobjqueue, totransitem);");
+ output.println(" removeItem(desqueue, desitem);");
+ output.println("}");
+ output.println("freeQueue(totransobjqueue);");
+ output.println("freeQueue(desqueue);");
+ }
+
+ protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
+ if (frn.getReturnTemp()!=null) {
+ if (frn.getReturnTemp().getType().isPtr())
+ output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
+ else
+ output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
+ } else {
+ if(fm.getTask() != null) {
+ outputTransCode(output);
+ }
+ output.println("return;");
+ }
+ }
}
\ No newline at end of file
FlatNew fn=new FlatNew(td, out_temp, con.isGlobal());
TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
FlatNode last=fn;
+ // Build arguments
+ for(int i=0;i<con.numArgs();i++) {
+ ExpressionNode en=con.getArg(i);
+ TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
+ temps[i]=tmp;
+ NodePair np=flattenExpressionNode(en, tmp);
+ last.addNext(np.getBegin());
+ last=np.getEnd();
+ }
+ MethodDescriptor md=con.getConstructor();
+ //Call to constructor
+ FlatCall fc=new FlatCall(md, null, out_temp, temps);
+ last.addNext(fc);
+ last=fc;
if (td.getClassDesc().hasFlags()) {
// if (con.getFlagEffects()!=null) {
FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
last.addNext(ffan);
last=ffan;
}
- //Build arguments
- for(int i=0;i<con.numArgs();i++) {
- ExpressionNode en=con.getArg(i);
- TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
- temps[i]=tmp;
- NodePair np=flattenExpressionNode(en, tmp);
- last.addNext(np.getBegin());
- last=np.getEnd();
- }
- MethodDescriptor md=con.getConstructor();
- //Call to constructor
- FlatCall fc=new FlatCall(md, null, out_temp, temps);
- last.addNext(fc);
- last=fc;
return new NodePair(fn,last);
} else {
FlatNode first=null;
scheduleAnalysis.schedule();
//simulate these schedulings
- ScheduleSimulator scheduleSimulator = new ScheduleSimulator(scheduleAnalysis.getCoreNum(), state, ta);
+ //ScheduleSimulator scheduleSimulator = new ScheduleSimulator(scheduleAnalysis.getCoreNum(), state, ta);
Iterator it_scheduling = scheduleAnalysis.getSchedulingsIter();
- int index = 0;
+ /*int index = 0;
Vector<Integer> selectedScheduling = new Vector<Integer>();
int processTime = Integer.MAX_VALUE;
while(it_scheduling.hasNext()) {
for(int i = 0; i < selectedScheduling.size(); i++) {
System.out.print(selectedScheduling.elementAt(i) + ", ");
}
- System.out.println();
+ System.out.println();*/
/*ScheduleSimulator scheduleSimulator = new ScheduleSimulator(4, state, ta);
Vector<Schedule> scheduling = new Vector<Schedule>();
#endif
struct Queue * createQueue() {
- return RUNMALLOC(sizeof(struct Queue));
+ return (struct Queue *)RUNMALLOC(sizeof(struct Queue));
}
void freeQueue(struct Queue * q) {
struct thread_data thread_data_array[NUMCORES];
mqd_t mqd[NUMCORES];
static pthread_key_t key;
+static struct RuntimeHash* locktbl;
+static pthread_rwlock_t rwlock_tbl;
+static pthread_rwlock_t rwlock_init;
+#endif
bool transStallMsg(int targetcore);
void transTerminateMsg(int targetcore);
void run(void * arg);
-#endif
+bool getreadlock(void* ptr);
+void releasereadlock(void* ptr);
+bool getwritelock(void* ptr);
+void releasewritelock(void* ptr);
int main(int argc, char **argv) {
#ifdef THREADSIMULATE
+ errno = 0;
int tids[NUMCORES];
int rc[NUMCORES];
pthread_t threads[NUMCORES];
int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
mq_unlink(path);
mqd[i]= mq_open(path, oflags, omodes, NULL);
+ if(mqd[i] == -1) {
+ printf("[Main] mq_open %s fails: %d, error: %s\n", path, mqd[i], strerror(errno));
+ exit(-1);
+ } else {
+ printf("[Main] mq_open %s returns: %d\n", path, mqd[i]);
+ }
}
// create the key
pthread_key_create(&key, NULL);
+ // create the lock table and initialize its mutex
+ locktbl = allocateRuntimeHash(20);
+ int rc_locktbl = pthread_rwlock_init(&rwlock_tbl, NULL);
+ printf("[Main] initialize the rwlock for lock table: %d error: \n", rc_locktbl, strerror(rc_locktbl));
+
/* if(argc < 2) {
printf("Usage: <bin> <corenum>\n");
fflush(stdout);
thread_data_array[i].argv = argv;
thread_data_array[i].numsendobjs = 0;
thread_data_array[i].numreceiveobjs = 0;
- printf("In main: creating thread %d\n", i);
+ printf("[main] creating thread %d\n", i);
rc[i] = pthread_create(&threads[i], NULL, run, (void *)&thread_data_array[i]);
if (rc[i]){
- printf("ERROR; return code from pthread_create() is %d\n", rc[i]);
+ printf("[main] ERROR; return code from pthread_create() is %d\n", rc[i]);
fflush(stdout);
exit(-1);
}
pthread_setspecific(key, (void *)my_tdata->corenum);
int argc = my_tdata->argc;
char** argv = my_tdata->argv;
- printf("Thread %d runs: %x\n", my_tdata->corenum, (int)pthread_self());
+ printf("[run, %d] Thread %d runs: %x\n", my_tdata->corenum, my_tdata->corenum, (int)pthread_self());
fflush(stdout);
#endif
while(true) {
switch(receiveObject()) {
case 0: {
- printf("[run] receive an object\n");
+ printf("[run, %d] receive an object\n", numofcore);
sendStall = false;
// received an object
// check if there are new active tasks can be executed
break;
}
case 1: {
- //printf("[run] no msg\n");
+ //printf("[run, %d] no msg\n", numofcore);
// no msg received
if(STARTUPCORE == numofcore) {
corestatus[numofcore] = 0;
}
}
mq_close(mqd[corenum]);*/
- printf("[run] terminate!\n");
+
+ // release all locks
+ struct RuntimeIterator* it_lock = RuntimeHashcreateiterator(locktbl);
+ while(0 != RunhasNext(it_lock)) {
+ int key = Runkey(it_lock);
+ pthread_rwlock_t* rwlock_obj = (pthread_rwlock_t*)Runnext(it_lock);
+ int rc_des = pthread_rwlock_destroy(rwlock_obj);
+ printf("[run, %d] destroy the rwlock for object: %d error: \n", numofcore, key, strerror(rc_des));
+ }
+ freeRuntimeHash(locktbl);
+ locktbl = NULL;
+ RUNFREE(it_lock);
+
+ // destroy all message queues
+ char * pathhead = "/msgqueue_";
+ int targetlen = strlen(pathhead);
+ for(i = 0; i < NUMCORES; ++i) {
+ char corenumstr[3];
+ int sourcelen = 0;
+ if(i < 10) {
+ corenumstr[0] = i + '0';
+ corenumstr[1] = '\0';
+ sourcelen = 1;
+ } else if(i < 100) {
+ corenumstr[1] = i %10 + '0';
+ corenumstr[0] = (i / 10) + '0';
+ corenumstr[2] = '\0';
+ sourcelen = 2;
+ } else {
+ printf("Error: i >= 100\n");
+ fflush(stdout);
+ exit(-1);
+ }
+ char path[targetlen + sourcelen + 1];
+ strcpy(path, pathhead);
+ strncat(path, corenumstr, sourcelen);
+ mq_unlink(path);
+ }
+
+ printf("[run, %d] terminate!\n", numofcore);
fflush(stdout);
exit(0);
}
break;
}
case 2: {
- printf("[run] receive a stall msg\n");
+ printf("[run, %d] receive a stall msg\n", numofcore);
// receive a Stall Msg, do nothing
assert(STARTUPCORE == numofcore); // only startup core can receive such msg
sendStall = false;
break;
}
/* case 3: {
- printf("[run] receive a terminate msg\n");
+ printf("[run, %d] receive a terminate msg\n", numofcore);
// receive a terminate Msg
assert(STARTUPCORE != corenum); // only non-startup core can receive such msg
mq_close(mqd[corenum]);
break;
}*/
default: {
- printf("Error: invalid message type.\n");
+ printf("[run, %d] Error: invalid message type.\n", numofcore);
fflush(stdout);
exit(-1);
break;
((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;
}
+ startupobject->isolate = 1;
+ startupobject->version = 0;
+
/* Set initialized flag for startup object */
flagorandinit(startupobject,1,0xFFFFFFFF);
enqueueObject(startupobject, NULL, 0);
//printf( "umap ok \n" );
#endif
+ int numofcore = pthread_getspecific(key);
+
// use POSIX message queue to transfer objects between cores
mqd_t mqdnum;
char corenumstr[3];
char path[targetlen + sourcelen + 1];
strcpy(path, pathhead);
strncat(path, corenumstr, sourcelen);
- int oflags = O_WRONLY|O_CREAT|O_NONBLOCK;
+ int oflags = O_WRONLY|O_NONBLOCK;
int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
mqdnum = mq_open(path, oflags, omodes, NULL);
if(mqdnum==-1) {
- printf("[transferObject] mq_open fail: %d, error: %s\n", mqdnum, strerror(errno));
+ printf("[transferObject, %d] mq_open %s fail: %d, error: %s\n", numofcore, path, mqdnum, strerror(errno));
fflush(stdout);
exit(-1);
}
+ struct ___Object___ * newobj = (struct ___Object___ *)obj;
+ if(0 == newobj->isolate) {
+ newobj = RUNMALLOC(size);
+ memcpy(newobj, obj, size);
+ newobj->original=obj;
+ }
int ret;
do {
- ret=mq_send(mqdnum, obj, size, 0); // send the object into the queue
+ ret=mq_send(mqdnum, (void *)newobj, size, 0); // send the object into the queue
if(ret != 0) {
- printf("[transferObject] mq_send returned: %d, error: %s\n", ret, strerror(errno));
+ printf("[transferObject, %d] mq_send to %s returned: %d, error: %s\n", numofcore, path, ret, strerror(errno));
}
- }while(ret!=0);
- int numofcore = pthread_getspecific(key);
+ }while(ret!=0);
if(numofcore == STARTUPCORE) {
++numsendobjs[numofcore];
} else {
++(thread_data_array[numofcore].numsendobjs);
}
- printf("[transferObject] mq_send returned: $%x\n",ret);
+ printf("[transferObject, %d] mq_send to %s returned: $%x\n", numofcore, path, ret);
#endif
}
char path[targetlen + sourcelen + 1];
strcpy(path, pathhead);
strncat(path, corenumstr, sourcelen);
- int oflags = O_WRONLY|O_CREAT|O_NONBLOCK;
+ int oflags = O_WRONLY|O_NONBLOCK;
int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
mqdnum = mq_open(path, oflags, omodes, NULL);
if(mqdnum==-1) {
- printf("[transStallMsg] mq_open fail: %d, error: %s\n", mqdnum, strerror(errno));
+ printf("[transStallMsg, %d] mq_open %s fail: %d, error: %s\n", numofcore, path, mqdnum, strerror(errno));
fflush(stdout);
exit(-1);
}
int ret;
ret=mq_send(mqdnum, (void *)&newobj, sizeof(struct ___Object___), 0); // send the object into the queue
if(ret != 0) {
- printf("[transStallMsg] mq_send returned: %d, error: %s\n", ret, strerror(errno));
+ printf("[transStallMsg, %d] mq_send to %s returned: %d, error: %s\n", numofcore, path, ret, strerror(errno));
return false;
} else {
- printf("[transStallMsg] mq_send returned: $%x\n", ret);
- printf("index: %d, sendobjs: %d, receiveobjs: %d\n", newobj.flag, newobj.___cachedHash___, newobj.___cachedCode___);
+ printf("[transStallMsg, %d] mq_send to %s returned: $%x\n", numofcore, path, ret);
+ printf("<transStallMsg> to %s index: %d, sendobjs: %d, receiveobjs: %d\n", path, newobj.flag, newobj.___cachedHash___, newobj.___cachedCode___);
return true;
}
#endif
char path[targetlen + sourcelen + 1];
strcpy(path, pathhead);
strncat(path, corenumstr, sourcelen);
- int oflags = O_WRONLY|O_CREAT|O_NONBLOCK;
+ int oflags = O_WRONLY|O_NONBLOCK;
int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
mqdnum = mq_open(path, oflags, omodes, NULL);
if(mqdnum==-1) {
//printf("msg: %s\n",msgptr);
if(((int*)msgptr)[0] == -1) {
// StallMsg
- int* tmpptr = (int*)msgptr;
- int index = tmpptr[1];
+ struct ___Object___ * tmpptr = (struct ___Object___ *)msgptr;
+ int index = tmpptr->flag;
corestatus[index] = 0;
- numsendobjs[index] = tmpptr[2];
- numreceiveobjs[index] = ((int *)(msgptr + sizeof(int) * 3 + sizeof(void *)))[0];
- printf("index: %d, sendobjs: %d, reveiveobjs: %d\n", index, numsendobjs[index], numreceiveobjs[index]);
+ numsendobjs[index] = tmpptr->___cachedHash___;
+ numreceiveobjs[index] = tmpptr->___cachedCode___;
+ printf("<receiveObject> index: %d, sendobjs: %d, reveiveobjs: %d\n", index, numsendobjs[index], numreceiveobjs[index]);
free(msgptr);
return 2;
} /*else if(((int*)msgptr)[0] == -2) {
#endif
}
+bool getreadlock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+ int numofcore = pthread_getspecific(key);
+
+ int rc = pthread_rwlock_tryrdlock(&rwlock_tbl);
+ printf("[getreadlock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ if(EBUSY == rc) {
+ return false;
+ }
+ if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+ // no locks for this object
+ // first time to operate on this shared object
+ // create a lock for it
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[getreadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ pthread_rwlock_t* rwlock = (pthread_rwlock_t *)RUNMALLOC(sizeof(pthread_rwlock_t));
+ memcpy(rwlock, &rwlock_init, sizeof(pthread_rwlock_t));
+ rc = pthread_rwlock_init(rwlock, NULL);
+ printf("[getreadlock, %d] initialize the rwlock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
+ rc = pthread_rwlock_trywrlock(&rwlock_tbl);
+ printf("[getreadlock, %d] getting the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ if(EBUSY == rc) {
+ return false;
+ } else {
+ RuntimeHashadd(locktbl, (int)ptr, (int)rwlock);
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[getreadlock, %d] release the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ }
+ //rc = pthread_rwlock_rdlock(&rwlock);
+ rc = pthread_rwlock_tryrdlock(rwlock);
+ printf("[getreadlock, %d] getting read lock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
+ if(EBUSY == rc) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ pthread_rwlock_t* rwlock_obj = NULL;
+ RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[getreadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ //int rc_obj = pthread_rwlock_rdlock(&rwlock_obj);
+ int rc_obj = pthread_rwlock_tryrdlock(rwlock_obj);
+ printf("[getreadlock, %d] getting read lock for object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+ if(EBUSY == rc_obj) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+#endif
+}
+
+void releasereadlock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+ int numofcore = pthread_getspecific(key);
+ int rc = pthread_rwlock_rdlock(&rwlock_tbl);
+ printf("[releasereadlock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+ printf("[releasereadlock, %d] Error: try to release a lock without previously grab it\n", numofcore);
+ exit(-1);
+ }
+ pthread_rwlock_t* rwlock_obj = NULL;
+ RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+ int rc_obj = pthread_rwlock_unlock(rwlock_obj);
+ printf("[releasereadlock, %d] unlocked object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[releasereadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+#endif
+}
+
+bool getwritelock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+ int numofcore = pthread_getspecific(key);
+
+ int rc = pthread_rwlock_tryrdlock(&rwlock_tbl);
+ printf("[getwritelock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ if(EBUSY == rc) {
+ return false;
+ }
+ if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+ // no locks for this object
+ // first time to operate on this shared object
+ // create a lock for it
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[getwritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ pthread_rwlock_t* rwlock = (pthread_rwlock_t *)RUNMALLOC(sizeof(pthread_rwlock_t));
+ memcpy(rwlock, &rwlock_init, sizeof(pthread_rwlock_t));
+ rc = pthread_rwlock_init(rwlock, NULL);
+ printf("[getwritelock, %d] initialize the rwlock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
+ rc = pthread_rwlock_trywrlock(&rwlock_tbl);
+ printf("[getwritelock, %d] getting the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ if(EBUSY == rc) {
+ return false;
+ } else {
+ RuntimeHashadd(locktbl, (int)ptr, (int)rwlock);
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[getwritelock, %d] release the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ }
+ //rc = pthread_rwlock_wrlock(rwlock);
+ rc = pthread_rwlock_trywrlock(rwlock);
+ printf("[getwritelock, %d] getting write lock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
+ if(EBUSY == rc) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ pthread_rwlock_t* rwlock_obj = NULL;
+ RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[getwritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ //int rc_obj = pthread_rwlock_wrlock(rwlock_obj);
+ int rc_obj = pthread_rwlock_trywrlock(rwlock_obj);
+ printf("[getwritelock, %d] getting write lock for object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+ if(EBUSY == rc_obj) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+#endif
+}
+
+void releasewritelock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+ int numofcore = pthread_getspecific(key);
+ int rc = pthread_rwlock_rdlock(&rwlock_tbl);
+ printf("[releasewritelock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+ if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+ printf("[releasewritelock, %d] Error: try to release a lock without previously grab it\n", numofcore);
+ exit(-1);
+ }
+ pthread_rwlock_t* rwlock_obj = NULL;
+ RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+ int rc_obj = pthread_rwlock_unlock(rwlock_obj);
+ printf("[releasewritelock, %d] unlocked object %d: %d error:\n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+ rc = pthread_rwlock_unlock(&rwlock_tbl);
+ printf("[releasewritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+#endif
+}
+
int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
void * taskpointerarray[MAXTASKPARAMS];
int j;
int numparams=currtpd->task->numParameters;
int numtotal=currtpd->task->numTotal;
+ int isolateflags[numparams];
/* Make sure that the parameters are still in the queues */
for(i=0;i<numparams;i++) {
void * parameter=currtpd->parameterArray[i];
+ struct ___Object___ * tmpparam = (struct ___Object___ *)parameter;
+ if(0 == tmpparam->isolate) {
+ isolateflags[i] = 0;
+ // shared object, need to flush with current value
+ //if(!getreadlock(tmpparam->original)) {
+ // // fail to get read lock of the original object, try this task later
+ if(!getwritelock(tmpparam->original)) {
+ // fail to get write lock, release all obtained locks and try this task later
+ int j = 0;
+ for(j = 0; j < i; ++j) {
+ if(0 == isolateflags[j]) {
+ releasewritelock(taskpointerarray[j]);
+ }
+ }
+ genputtable(activetasks, currtpd, currtpd);
+ goto newtask;
+ }
+ if(tmpparam->version != tmpparam->original->version) {
+ // flush this object
+ memcpy(tmpparam, tmpparam->original, classsize[tmpparam->type]);
+ //releasereadlock(tmpparam->original);
+ // fail to get write lock, release all obtained locks and try this task later
+ int j = 0;
+ for(j = 0; j < i; ++j) {
+ if(0 == isolateflags[j]) {
+ releasewritelock(((struct ___Object___ *)taskpointerarray[j+OFFSET])->original);
+ }
+ }
+ releasewritelock(tmpparam->original);
+
+ // some task on another core has changed this object
+ // Free up task parameter descriptor
+ RUNFREE(currtpd->parameterArray);
+ RUNFREE(currtpd);
+ // dequeue this object
+#ifdef THREADSIMULATE
+ int numofcore = pthread_getspecific(key);
+ struct parameterwrapper ** queues = objectqueues[numofcore][tmpparam->type];
+ int length = numqueues[numofcore][tmpparam->type];
+#else
+ struct parameterwrapper ** queues = objectqueues[corenum][tmpparam->type];
+ int length = numqueues[corenum][tmpparam->type];
+#endif
+ for(j = 0; j < length; ++j) {
+ struct parameterwrapper * pw = queues[j];
+ if(ObjectHashcontainskey(pw->objectset, (int)tmpparam)) {
+ int next;
+ int UNUSED, UNUSED2;
+ int * enterflags;
+ ObjectHashget(pw->objectset, (int) tmpparam, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
+ ObjectHashremove(pw->objectset, (int)tmpparam);
+ if (enterflags!=NULL)
+ free(enterflags);
+ }
+ }
+ // try to enqueue it again to check if it feeds other tasks;
+ enqueueObject(tmpparam, NULL, 0);
+ goto newtask;
+ }
+ //releasereadlock(tmpparam->original);
+ } else {
+ isolateflags[i] = 1;
+ }
struct parameterdescriptor * pd=currtpd->task->descriptorarray[i];
struct parameterwrapper *pw=(struct parameterwrapper *) pd->queue;
int j;
taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
}
+ for(i = 0; i < numparams; ++i) {
+ if(0 == isolateflags[i]) {
+ struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
+ // shared object, need to replace this copy with original one
+ /*if(!getwritelock(tmpparam->original)) {
+ // fail to get write lock, release all obtained locks and try this task later
+ int j = 0;
+ for(j = 0; j < i; ++j) {
+ if(0 == isolateflags[j]) {
+ releasewritelock(taskpointerarray[j]);
+ }
+ }
+ genputtable(activetasks, tpd, tpd);
+ goto newtask;
+ }*/
+ if(tmpparam != tmpparam->original) {
+ taskpointerarray[i+OFFSET] = tmpparam->original;
+ }
+ }
+ }
+
{
/* Checkpoint the state */
forward=allocateRuntimeHash(100);
} else
((void (*) (void **)) currtpd->task->taskptr)(taskpointerarray);
+ for(i = 0; i < numparams; ++i) {
+ if(0 == isolateflags[i]) {
+ struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
+ releasewritelock(tmpparam);
+ }
+ }
+
freeRuntimeHash(forward);
freeRuntimeHash(reverse);
freemalloc();
#endif
int j;
- /* Build iterators for parameters */
- for(j=0;j<task->numParameters;j++) {
+ /* Build objectsets */
+ for(j=0;j<task->numParameters;j++) {
struct parameterdescriptor *param=task->descriptorarray[j];
struct parameterwrapper *parameter=param->queue;
parameter->objectset=allocateObjectHash(10);
parameter->task=task;
+ }
+
+ /* Build iterators for parameters */
+ for(j=0;j<task->numParameters;j++) {
+ struct parameterdescriptor *param=task->descriptorarray[j];
+ struct parameterwrapper *parameter=param->queue;
builditerators(task, j, parameter);
}
}