package s3scj.tck;
import javax.realtime.MemoryInUseException;
import javax.realtime.PeriodicParameters;
import javax.realtime.PriorityParameters;
import javax.realtime.RelativeTime;
import javax.realtime.ScopedCycleException;
import javax.safetycritical.MissionSequencer;
import javax.safetycritical.PeriodicEventHandler;
import javax.safetycritical.PrivateMemory;
/**
* @author leizhao
*
* Assertion:
*
* - A given scoped memory can only be entered by a single thread at any
* given time;
*/
public class TestMemory502 extends TestCase {
public MissionSequencer getSequencer() {
return new GeneralSingleMissionSequencer(new GeneralMission() {
private final int _nScopeInvaders = 5;
final private MyLock _myLock = new MyLock();
@Override
public void initialize() {
final PrivateMemory scope = new PrivateMemory(5000);
class ScopeInvader extends PeriodicEventHandler {
public ScopeInvader() {
super(new PriorityParameters(_prop._priority),
new PeriodicParameters(null, new RelativeTime(
500000, 0)), _prop._schedObjMemSize);
}
@Override
public void handleEvent() {
try {
scope.enter(new Runnable() {
public void run() {
try {
_myLock.doWait();
}
catch (InterruptedException e) {
fail(e.getMessage());
}
};
});
}
catch (MemoryInUseException miue) {
// These are expected, since they should be thrown
// when a thread is already in a scope
}
catch (ScopedCycleException sce) {
fail("Multiple handlers entered a private memory simultaneously (scope cycle)");
}
catch (Throwable t) {
fail(t.getMessage());
}
}
}
/*
* Create more than one scope memory invaders which will try to
* enter the "scope" memory at the same time. They should fail
* to do that.
*/
for (int i = 0; i < _nScopeInvaders; i++)
new ScopeInvader();
/*
* Wait for reasonable long a time so that all invaders should
* have entered the scope if they can. Notify all invaders and
* terminate the mission.
*/
new PeriodicEventHandler(
new PriorityParameters(_prop._priority),
new PeriodicParameters(null,
new RelativeTime(500000, 0)),
_prop._schedObjMemSize) {
@Override
public void handleEvent() {
try {
Thread.sleep(2000);
}
catch (InterruptedException e) {
fail(e.getMessage());
}
_myLock.doNotifyAll();
requestSequenceTermination();
}
};
}
@Override
public long missionMemorySize() {
return 5000 * _nScopeInvaders;
}
class MyLock {
public synchronized void doWait() throws InterruptedException {
this.wait();
}
public synchronized void doNotifyAll() {
this.notifyAll();
}
}
});
}
}