package hj.runtime.wsh;
import hj.lang.Future;
import hj.lang.Runtime;
import hj.lang.phaser;
import hj.lang.phaserMode;
import hj.runtime.wsh.phaser.PhaserRegModeImpl;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class Activity extends Thread {
// Name is part of Activity interface, but not used
private String name;
// Descendants contains all Finish scopes the activity has
private Stack<FinishScope> descendants;
// InheritedFinishScope is the finish scope the activity is in
private FinishScope scopeBelongsTo;
Future future;
int ID;
private LinkedList<PhaserRegModeImpl> phasers;
public Activity (LinkedList<PhaserRegModeImpl> phaserArgs, String n) {
name=n;
phasers=phaserArgs;
setup();
}
public Activity(String n) {
name=n;
phasers=new LinkedList<PhaserRegModeImpl> ();
setup();
}
@Override
public void run() {
try {
runHjTask();
} finally {
releaseLocks();
unregisterFromPhasers();
}
}
public void runHjTask() {}
// Interface with calls made from compiled code. Task is always ready
public boolean isHjTaskReady() {
return true;
}
// Interface with calls made from compiled code. No need to set data driven futures
public void setDDF(Collection c) {}
private void setup() {
future = new Future();
descendants = new Stack<FinishScope>();
ID = Runtime.getUniqueActivityID();
if (name.endsWith("$Main")) {
// First activity (main) must set up a brand new finish scope
scopeBelongsTo = new FinishScope();
} else {
// Add self to parent's most recent finish scope or parent's own scope
Activity parentThread = (Activity) Thread.currentThread();
scopeBelongsTo = parentThread.getCurrentFinishScope();
scopeBelongsTo.add(this);
}
Iterator<PhaserRegModeImpl> it = phasers.iterator();
while (it.hasNext()) {
PhaserRegModeImpl phImpl = it.next();
// Wait modes are the only ones that dont need to signal
if (phImpl.getMode()!=phaserMode.WAIT) {
phImpl.getPhaser().registerSignaler(this);
}
// Signal modes are the only ones that dont need to wait
if (phImpl.getMode() != phaserMode.SIG) {
phImpl.getPhaser().registerWaiter(this);
}
}
}
// Get the FinishScope a newly created task would belong to
public FinishScope getCurrentFinishScope() {
if (descendants.empty() == true) {
return scopeBelongsTo;
} else {
return descendants.peek();
}
}
// Special finish that we have yet to trigger in the runtime
public void startFinish(final java.lang.Object accums) {}
public void startFinish() {
descendants.push(new FinishScope());
}
public void pushException(Throwable t) {
// Uncomment if there is an expection
System.out.println(t);
t.printStackTrace();
}
public void stopFinish() {
FinishScope children = null;
children = descendants.pop();
/*When the parent task hits the end finish statement we have chosen
* to unregister from all phasers within that finish scope. As far as we
* can tell this should emulate the proper behave of HJ.
*/
children.unregisterAllPhasers(this);
// Join on all activities in the finish scope
while (children.size() > 0) {
Activity child = (Activity) children.poll();
try {child.join();} catch (Exception e) {}
}
}
private void releaseLocks() {
if (Runtime.getLock().isHeldByCurrentThread()) {
while (Runtime.getLock().getHoldCount() > 0) {
Runtime.getLock().unlock();
}
}
}
public Future getFuture() {
return future;
}
public void setAsyncReturn(java.lang.Object object) {
future.setFuture(object);
}
public String getActivityName() {
return name;
}
// TODO: When error checking is done, make this throw errors
public void checkPhaserUse(LinkedList checkPhasers) {
// Makes sure a task's modes are subsets of the phasers
Iterator<PhaserRegModeImpl> it = (Iterator<PhaserRegModeImpl>)checkPhasers.iterator();
while (it.hasNext()) {
PhaserRegModeImpl phaserArg = it.next();
if (!checkPhaserModeSubset(phaserArg.getPhaser().getMode(), phaserArg.getMode())) {
// Throw error for a task's mode being outside the heirarchy of phaser's mode
}
}
// Makes sure a task's modes are subsets of phasers the parent is in
it = (Iterator<PhaserRegModeImpl>)checkPhasers.iterator();
while (it.hasNext()) {
PhaserRegModeImpl phaserArg = it.next();
Iterator<PhaserRegModeImpl> parentit = (Iterator<PhaserRegModeImpl>)phasers.iterator();
while (parentit.hasNext()) {
PhaserRegModeImpl parentPhaserArg = parentit.next();
if (parentPhaserArg.getPhaser()==phaserArg.getPhaser()) {
if (!checkPhaserModeSubset(parentPhaserArg.getMode(),phaserArg.getMode())) {
// Throw error for a task's mode being outside the heirarchy of a parent's phaser mode
}
}
}
}
}
// Returns true if heirarchy of superset is equal or greater than subset
private boolean checkPhaserModeSubset(phaserMode superSet, phaserMode subSet) {
if (superSet==subSet)
return true;
if (superSet==phaserMode.SIG_WAIT_SINGLE)
return true;
if (subSet==phaserMode.SIG_WAIT_SINGLE)
return false;
if (superSet==phaserMode.SIG_WAIT)
return true;
return false;
}
// Non-blocking signal to all phasers
public void doSignal() {
Iterator<PhaserRegModeImpl> iterator = phasers.iterator();
while (iterator.hasNext()) {
PhaserRegModeImpl phArgs = iterator.next();
// Wait modes are the only ones that dont need to signal
if (phArgs.getMode()!=phaserMode.WAIT)
phArgs.getPhaser().phSignal(this);
}
}
public void doNext() {
//First signal all phasers
doSignal();
//Next wait on all phasers
Iterator<PhaserRegModeImpl> iterator = phasers.iterator();
while (iterator.hasNext()) {
PhaserRegModeImpl phArgs = iterator.next();
// Sig modes are the only ones that dont need to wait
if (phArgs.getMode()!=phaserMode.SIG)
phArgs.getPhaser().phWait(this);
}
}
public int doNext1(final String loc) {
int isFirstSingle=0;
LinkedList<phaser> singlePhasers = new LinkedList<phaser>();
//First signal all phasers
Iterator<PhaserRegModeImpl> iterator = phasers.iterator();
while (iterator.hasNext()) {
PhaserRegModeImpl phArgs = iterator.next();
// If it is a single mode, do signalSingle
if (phArgs.getMode()==phaserMode.SIG_WAIT_SINGLE) {
if (phArgs.getPhaser().phSignalSingle(this)) {
isFirstSingle++;
singlePhasers.add(phArgs.getPhaser());
}
continue;
}
// Wait modes are the only ones that dont need to signal
if (phArgs.getMode()!=phaserMode.WAIT)
phArgs.getPhaser().phSignal(this);
}
if (isFirstSingle>0) {
Iterator<phaser> it = singlePhasers.iterator();
while (it.hasNext()) {
phaser ph = it.next();
ph.holdSingle(this);
}
}
return isFirstSingle;
}
public void doNext2() {
Iterator<PhaserRegModeImpl> iterator = phasers.iterator();
while (iterator.hasNext()) {
PhaserRegModeImpl phArgs = iterator.next();
if (phArgs.getMode()==phaserMode.SIG_WAIT_SINGLE) {
phArgs.getPhaser().phWaitSingle(this);
} else if (phArgs.getMode()!=phaserMode.SIG) {
phArgs.getPhaser().phWait(this);
}
}
}
public void addPhaser(PhaserRegModeImpl phImpl) {
phasers.add(phImpl);
}
private void unregisterFromPhasers() {
scopeBelongsTo.unregisterAllPhasers(this);
}
public List getPhaserRegModeList() {
return phasers;
}
}