/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
Copyright (C) 2008-2011, Martin Schoeberl (martin@jopdesign.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package javax.safetycritical;
import static javax.safetycritical.annotate.Level.LEVEL_2;
import static javax.safetycritical.annotate.Level.SUPPORT;
import static javax.safetycritical.annotate.Level.INFRASTRUCTURE;
import javax.realtime.BoundAsyncEventHandler;
import javax.realtime.PriorityParameters;
import javax.safetycritical.annotate.MemoryAreaEncloses;
import javax.safetycritical.annotate.SCJAllowed;
import javax.safetycritical.annotate.SCJRestricted;
import com.jopdesign.sys.RtThreadImpl;
import joprt.RtThread;
import joprt.SwEvent;
import static javax.safetycritical.annotate.Phase.INITIALIZATION;
/**
* That's the root of (all evil ;-), no the main startup logic...
*
* @author Martin Schoeberl
*
* @param <SpecificMission>
*/
@SCJAllowed
public abstract class MissionSequencer<SpecificMission extends Mission> extends
ManagedEventHandler {
private SwEvent clean;
// private boolean cleanupDidRun;
public static boolean cleanupDidRun;
Mission current_mission;
// why is this static?
// ok, in level 1 we have only one mission.
// But it is ugly that Mission does not know about its
// sequencer and therefore cannot call the termination on
// a specific one.
static boolean terminationRequest = false;
/**
* The constructor just sets the initial state.
*
* @param priority
* @param storage
* @param name
*/
@SCJAllowed
@MemoryAreaEncloses(inner = { "this", "this", "this" }, outer = {
"priority", "storage", "name" })
@SCJRestricted(phase = INITIALIZATION)
public MissionSequencer(PriorityParameters priority,
StorageParameters storage, String name) {
// MS: just to make the system happy, but we don't want to
// really extend the handler.... We want to run in the
// plain Java thread!
// in Level 1 we can simply ignore the priority
super(priority, null, storage, name);
// just an idle thread that watches the termination request
// We should use the inital main thread to watch for termination...
new RtThread(0, 10000) {
public void run() {
while (!MissionSequencer.terminationRequest) {
waitForNextPeriod();
}
// Why do we need to call the cleanUp() method of the next
// mission after a termination request in the current mission?
//getNextMission().cleanUp();
// Current mission cleanup method
current_mission.cleanUp();
// MEH cleanUp method
cleanUp();
cleanupDidRun = true;
}
};
// final Runnable runner = new Runnable() {
//
// public void run() {
// handleAsyncEvent();
//
// }
// };
//
// new RtThread(0, 10000){
//
// public void run() {
// while (!MissionSequencer.terminationRequest) {
//
// // This should be the mission memory
// privMem.enter(runner);
// block();
//// waitForNextPeriod();
// }
// // Current mission cleanup method
// current_mission.cleanUp();
//
// // MEH cleanUp method
// cleanUp();
// }
// };
// clean = new SwEvent(0, 100) {
// public void handle() {
// if (!cleanupDidRun && terminationRequest) {
// cleanup();
// }
// }
// };
}
@SCJAllowed
@MemoryAreaEncloses(inner = { "this" }, outer = { "priority" })
@SCJRestricted(phase = INITIALIZATION)
public MissionSequencer(PriorityParameters priority,
StorageParameters storage) {
this(priority, storage, "");
}
@SCJAllowed(SUPPORT)
protected abstract SpecificMission getNextMission();
/**
* Inherited because we extend MEH although we could use composition....
*/
@Override
@SCJAllowed(INFRASTRUCTURE)
public final void handleAsyncEvent() {
// current_mission.setSequencer(this);
// System.out.println("getting new mission");
//
//// if (current_mission.phase == Mission.INACTIVE){
// // Currently used as a means to start the single mission from another package
// Mission mission = getNextMission();
//
// mission.phase = Mission.INITIALIZATION;
//
// // TODO: The spec mentions something about mission memory resize...
// // mission.missionMemorySize();
//
// mission.initialize();
// }
}
/**
* Inherited because we extend MEH although we could use composition....
*/
@SCJAllowed
@SCJRestricted(phase = INITIALIZATION)
public final void register() {
// NOOP in Level 1
}
@SCJAllowed(LEVEL_2)
public final void requestSequenceTermination() {
// Why do we need to call the cleanUp() method of the next
// mission after a termination request in the current mission?
//this.getNextMission().requestTermination();
current_mission.requestTermination();
}
@SCJAllowed(LEVEL_2)
public final boolean sequenceTerminationPending() {
return false;
}
}