package edu.purdue.scjtck.tck;
import javax.realtime.AbsoluteTime;
import javax.realtime.Clock;
import javax.realtime.PeriodicParameters;
import javax.realtime.PriorityParameters;
import javax.realtime.PriorityScheduler;
import javax.realtime.RelativeTime;
import javax.safetycritical.MissionSequencer;
import javax.safetycritical.PeriodicEventHandler;
//import javax.safetycritical.StorageConfigurationParameters;
import javax.safetycritical.StorageParameters;
import javax.safetycritical.annotate.Level;
import javax.safetycritical.annotate.SCJAllowed;
/**
* Level 1
*
* - full preemptively scheduling shall be supported Level 1+
*/
public class TestSchedule405 extends TestCase {
@Override
protected String getArgs() {
return "-L 1";
}
public MissionSequencer getSequencer() {
return new GeneralSingleMissionSequencer(new GeneralMission() {
/*
* the time of lowStart, highStart, highEnd, medianStart, medianEnd,
* lowEnd in order
*/
private long[] _timeRecord = new long[6];
public void initialize() {
int MAX_PRIORITY = PriorityScheduler.instance()
.getMaxPriority();
int NOR_PRIORITY = PriorityScheduler.instance()
.getNormPriority();
int MIN_PRIORITY = PriorityScheduler.instance()
.getMinPriority();
PriorityParameters high = new PriorityParameters(
(MAX_PRIORITY - NOR_PRIORITY) / 2 + NOR_PRIORITY);
PriorityParameters median = new PriorityParameters(NOR_PRIORITY);
PriorityParameters low = new PriorityParameters(NOR_PRIORITY
- (NOR_PRIORITY - MIN_PRIORITY) / 2);
/*
* start time order: low -> high -> median
*
* high and median are supposed to preempt the execution of low,
* so we should have following order:
*
* lowStart -> highStart -> highEnd -> medianStart -> medianEnd
* -> lowEnd
*/
new PeriodicEventHandler(low, new PeriodicParameters(null,
new RelativeTime(Long.MAX_VALUE, 0)),
new StorageParameters(_prop._schedObjBackStoreSize,
null), _prop._schedObjScopeSize) {
@Override
public void handleAsyncEvent() {
// Terminal.getTerminal().writeln("low starts");
_timeRecord[0] = getCurrentTimeInNano();
doWorks();
_timeRecord[5] = getCurrentTimeInNano();
// Terminal.getTerminal().writeln("low finishes");
}
};
new PeriodicEventHandler(high, new PeriodicParameters(
new RelativeTime(5, 0), new RelativeTime(
Long.MAX_VALUE, 0)), new StorageParameters(
_prop._schedObjBackStoreSize, null),
_prop._schedObjScopeSize) {
@Override
public void handleAsyncEvent() {
// Terminal.getTerminal().writeln("high starts");
_timeRecord[1] = getCurrentTimeInNano();
doWorks();
_timeRecord[2] = getCurrentTimeInNano();
// Terminal.getTerminal().writeln("high finishes");
}
};
new PeriodicEventHandler(median, new PeriodicParameters(
new RelativeTime(10, 0), new RelativeTime(
Long.MAX_VALUE, 0)), new StorageParameters(
_prop._schedObjBackStoreSize, null),
_prop._schedObjScopeSize) {
@Override
public void handleAsyncEvent() {
// Terminal.getTerminal().writeln("median starts");
_timeRecord[3] = getCurrentTimeInNano();
doWorks();
_timeRecord[4] = getCurrentTimeInNano();
// Terminal.getTerminal().writeln("median finishes");
}
};
new Terminator();
}
// take around ? ms
private void doWorks() {
// for (int i = 0; i < 100000000; i++)
for (int i = 0; i < 100000; i++)
;
}
@Override
// public void cleanup() {
public void cleanUp() {
for (int i = 0; i < 5; i++)
if (_timeRecord[i] > _timeRecord[i + 1])
fail("Error in preemptive scheduling");
// super.cleanup();
super.cleanUp();
}
private long getCurrentTimeInNano() {
AbsoluteTime time = Clock.getRealtimeClock().getTime();
long nanos = time.getMilliseconds() * 1000000
+ time.getNanoseconds();
if (nanos < 0)
nanos = Long.MAX_VALUE;
return nanos;
}
});
}
@Override
@SCJAllowed(Level.SUPPORT)
public long immortalMemorySize() {
// TODO Auto-generated method stub
return 0;
}
}