// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov Date: 26/10/2010 14:02:41
// Home Page: http://members.fortunecity.com/neshkov/dj.html http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3)
package org.jcsp.lang;
// Referenced classes of package org.jcsp.lang:
// MultiwaySynchronisation, ProcessInterruptedException, JCSP_InternalError, Spurious,
// SpuriousLog, AltingBarrierCoordinate, Guard
public class Alternative
{
protected Object altMonitor;
private static final int enabling = 0;
private static final int waiting = 1;
private static final int ready = 2;
private static final int inactive = 3;
private int state;
private final Guard guard[];
private int favourite;
private int selected;
private final int NONE_SELECTED = -1;
private boolean barrierPresent;
private boolean barrierTrigger;
private int barrierSelected;
private int enableIndex;
private boolean timeout;
private long msecs;
private int timeIndex;
public Alternative(Guard aguard[])
{
altMonitor = new Object();
state = 3;
favourite = 0;
barrierTrigger = false;
timeout = false;
guard = aguard;
for(int i = 0; i < aguard.length; i++)
if(aguard[i] instanceof MultiwaySynchronisation)
{
barrierPresent = true;
return;
}
barrierPresent = false;
}
public final int select()
{
return fairSelect();
}
public final int priSelect()
{
state = 0;
favourite = 0;
enableGuards();
synchronized(altMonitor)
{
label0:
{
label1:
{
if(state != 0)
break label0;
state = 1;
try
{
if(timeout)
{
long l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break label1;
altMonitor.wait(l);
do
{
if(state != 1)
break label1;
l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break;
if(Spurious.logging)
SpuriousLog.record(33);
altMonitor.wait(l);
} while(true);
if(l > 0L && Spurious.logging)
SpuriousLog.incEarlyTimeouts();
} else
{
altMonitor.wait();
while(state == 1)
{
if(Spurious.logging)
SpuriousLog.record(32);
altMonitor.wait();
}
}
}
catch(InterruptedException interruptedexception)
{
throw new ProcessInterruptedException("*** Thrown from Alternative.priSelect ()\n" + interruptedexception.toString());
}
}
state = 2;
}
}
break MISSING_BLOCK_LABEL_220;
exception;
throw exception;
disableGuards();
state = 3;
timeout = false;
return selected;
}
public final int fairSelect()
{
state = 0;
enableGuards();
synchronized(altMonitor)
{
label0:
{
label1:
{
if(state != 0)
break label0;
state = 1;
try
{
if(timeout)
{
long l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break label1;
altMonitor.wait(l);
do
{
if(state != 1)
break label1;
l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break;
if(Spurious.logging)
SpuriousLog.record(33);
altMonitor.wait(l);
} while(true);
if(l > 0L && Spurious.logging)
SpuriousLog.incEarlyTimeouts();
} else
{
altMonitor.wait();
while(state == 1)
{
if(Spurious.logging)
SpuriousLog.record(32);
altMonitor.wait();
}
}
}
catch(InterruptedException interruptedexception)
{
throw new ProcessInterruptedException("*** Thrown from Alternative.fairSelect/select ()\n" + interruptedexception.toString());
}
}
state = 2;
}
}
break MISSING_BLOCK_LABEL_215;
exception;
throw exception;
disableGuards();
state = 3;
favourite = selected + 1;
if(favourite == guard.length)
favourite = 0;
timeout = false;
return selected;
}
private final void enableGuards()
{
if(barrierPresent)
AltingBarrierCoordinate.startEnable();
barrierSelected = -1;
for(enableIndex = favourite; enableIndex < guard.length; enableIndex++)
if(guard[enableIndex].enable(this))
{
selected = enableIndex;
state = 2;
if(barrierTrigger)
{
barrierSelected = selected;
barrierTrigger = false;
} else
if(barrierPresent)
AltingBarrierCoordinate.finishEnable();
return;
}
for(enableIndex = 0; enableIndex < favourite; enableIndex++)
if(guard[enableIndex].enable(this))
{
selected = enableIndex;
state = 2;
if(barrierTrigger)
{
barrierSelected = selected;
barrierTrigger = false;
} else
if(barrierPresent)
AltingBarrierCoordinate.finishEnable();
return;
}
selected = -1;
if(barrierPresent)
AltingBarrierCoordinate.finishEnable();
}
private void disableGuards()
{
if(selected != favourite)
{
int i = selected != -1 ? selected - 1 : favourite - 1;
if(i < favourite)
{
for(int j = i; j >= 0; j--)
{
if(!guard[j].disable())
continue;
selected = j;
if(!barrierTrigger)
continue;
if(barrierSelected != -1)
throw new JCSP_InternalError("*** Second AltingBarrier completed in ALT sequence: " + barrierSelected + " and " + j);
barrierSelected = selected;
barrierTrigger = false;
}
i = guard.length - 1;
}
for(int k = i; k >= favourite; k--)
{
if(!guard[k].disable())
continue;
selected = k;
if(!barrierTrigger)
continue;
if(barrierSelected != -1)
throw new JCSP_InternalError("\n*** Second AltingBarrier completed in ALT sequence: " + barrierSelected + " and " + k);
barrierSelected = selected;
barrierTrigger = false;
}
if(selected == -1)
selected = timeIndex;
}
if(barrierSelected != -1)
{
selected = barrierSelected;
AltingBarrierCoordinate.finishDisable();
}
}
void setTimeout(long l)
{
if(timeout)
{
if(l < msecs)
{
msecs = l;
timeIndex = enableIndex;
}
} else
{
timeout = true;
msecs = l;
timeIndex = enableIndex;
}
}
void setBarrierTrigger()
{
barrierTrigger = true;
}
void schedule()
{
synchronized(altMonitor)
{
switch(state)
{
case 0: // '\0'
state = 2;
break;
case 1: // '\001'
state = 2;
altMonitor.notify();
break;
}
}
}
public final int select(boolean aflag[])
{
return fairSelect(aflag);
}
public final int priSelect(boolean aflag[])
{
if(aflag.length != guard.length)
throw new IllegalArgumentException("*** org.jcsp.lang.Alternative.select called with a preCondition array\n*** whose length does not match its guard array");
state = 0;
favourite = 0;
enableGuards(aflag);
synchronized(altMonitor)
{
label0:
{
label1:
{
if(state != 0)
break label0;
state = 1;
try
{
if(timeout)
{
long l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break label1;
altMonitor.wait(l);
do
{
if(state != 1)
break label1;
l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break;
if(Spurious.logging)
SpuriousLog.record(33);
altMonitor.wait(l);
} while(true);
if(l > 0L && Spurious.logging)
SpuriousLog.incEarlyTimeouts();
} else
{
altMonitor.wait();
while(state == 1)
{
if(Spurious.logging)
SpuriousLog.record(32);
altMonitor.wait();
}
}
}
catch(InterruptedException interruptedexception)
{
throw new ProcessInterruptedException("*** Thrown from Alternative.priSelect (boolean[])\n" + interruptedexception.toString());
}
}
state = 2;
}
}
break MISSING_BLOCK_LABEL_241;
exception;
throw exception;
disableGuards(aflag);
state = 3;
timeout = false;
return selected;
}
public final int fairSelect(boolean aflag[])
{
if(aflag.length != guard.length)
throw new IllegalArgumentException("*** org.jcsp.lang.Alternative.select called with a preCondition array\n*** whose length does not match its guard array");
state = 0;
enableGuards(aflag);
synchronized(altMonitor)
{
label0:
{
label1:
{
if(state != 0)
break label0;
state = 1;
try
{
if(timeout)
{
long l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break label1;
altMonitor.wait(l);
do
{
if(state != 1)
break label1;
l = msecs - System.currentTimeMillis();
if(l <= Spurious.earlyTimeout)
break;
if(Spurious.logging)
SpuriousLog.record(33);
altMonitor.wait(l);
} while(true);
if(l > 0L && Spurious.logging)
SpuriousLog.incEarlyTimeouts();
} else
{
altMonitor.wait();
while(state == 1)
{
if(Spurious.logging)
SpuriousLog.record(32);
altMonitor.wait();
}
}
}
catch(InterruptedException interruptedexception)
{
throw new ProcessInterruptedException("*** Thrown from Alternative.fairSelect/select (boolean[])\n" + interruptedexception.toString());
}
}
state = 2;
}
}
break MISSING_BLOCK_LABEL_236;
exception;
throw exception;
disableGuards(aflag);
state = 3;
favourite = selected + 1;
if(favourite == guard.length)
favourite = 0;
timeout = false;
return selected;
}
private final void enableGuards(boolean aflag[])
{
if(barrierPresent)
AltingBarrierCoordinate.startEnable();
barrierSelected = -1;
for(enableIndex = favourite; enableIndex < guard.length; enableIndex++)
if(aflag[enableIndex] && guard[enableIndex].enable(this))
{
selected = enableIndex;
state = 2;
if(barrierTrigger)
{
barrierSelected = selected;
barrierTrigger = false;
} else
if(barrierPresent)
AltingBarrierCoordinate.finishEnable();
return;
}
for(enableIndex = 0; enableIndex < favourite; enableIndex++)
if(aflag[enableIndex] && guard[enableIndex].enable(this))
{
selected = enableIndex;
state = 2;
if(barrierTrigger)
{
barrierSelected = selected;
barrierTrigger = false;
} else
if(barrierPresent)
AltingBarrierCoordinate.finishEnable();
return;
}
selected = -1;
if(barrierPresent)
AltingBarrierCoordinate.finishEnable();
}
private void disableGuards(boolean aflag[])
{
if(selected != favourite)
{
int i = selected != -1 ? selected - 1 : favourite - 1;
if(i < favourite)
{
for(int j = i; j >= 0; j--)
{
if(!aflag[j] || !guard[j].disable())
continue;
selected = j;
if(!barrierTrigger)
continue;
if(barrierSelected != -1)
throw new JCSP_InternalError("*** Second AltingBarrier completed in ALT sequence: " + barrierSelected + " and " + j);
barrierSelected = selected;
barrierTrigger = false;
}
i = guard.length - 1;
}
for(int k = i; k >= favourite; k--)
{
if(!aflag[k] || !guard[k].disable())
continue;
selected = k;
if(!barrierTrigger)
continue;
if(barrierSelected != -1)
throw new JCSP_InternalError("*** Second AltingBarrier completed in ALT sequence: " + barrierSelected + " and " + k);
barrierSelected = selected;
barrierTrigger = false;
}
if(selected == -1)
selected = timeIndex;
}
if(barrierSelected != -1)
{
selected = barrierSelected;
AltingBarrierCoordinate.finishDisable();
}
}
}