_nextIterationTime = _stopTime;
// First look at interrupt events.
while (!_interruptQueue.isEmpty()) {
DEEvent interruptEvent = _interruptQueue.get();
Time timeStamp = interruptEvent.timeStamp();
if (timeStamp.compareTo(getModelTime()) < 0) {
// This should never happen.
throw new IllegalActionException(this,
"external input in the past: " + "input time stamp is "
+ timeStamp + "current time in TM is "
+ getModelTime());
} else if (timeStamp == getModelTime()) {
_interruptQueue.take();
Actor actor = interruptEvent.actor();
if (actor != null) {
if (actor.prefire()) {
actor.fire();
if (!actor.postfire()) {
_disableActor(actor);
}
}
}
} else {
// All interrupts are in the future.
// Get the time for the next interrupt.
// It will be used for finding the next iteration time.
_nextIterationTime = timeStamp;
break;
}
}
// Then we process TM events.
TMEvent event = null;
while (!_eventQueue.isEmpty()) {
event = (TMEvent) _eventQueue.get();
if (_debugging) {
_debug("The first event in the queue is ", event.toString());
}
// Notice that the first event in the queue
// either has processing time > 0 or hasn't been started.
if (!event.hasStarted()) {
if (_debugging) {
_debug(getName(), "put trigger event ", event.toString(),
" into " + ((NamedObj) event.actor()).getName()
+ " and processing");
}
event.receiver()._triggerEvent(event.token());
// FIXME: What shall we do if there are events to
// the same actor with the same priority.
// Check if there are any events with equal priority
// for this actor. If so, make them available to the
// actor at the same time.
Actor actor = event.actor();
if ((actor == getContainer()) || !actor.prefire()) {
// If the actor is the container of this director,
// then the event is at the output boundary.
// Remove the event and look at the next event.
_eventQueue.take();
event = null;
// Return to the while loop.
} else {
// Determine the processing time.
double processingTime = ((DoubleToken) defaultTaskExecutionTime
.getToken()).doubleValue();
if (actor instanceof TMActor) {
processingTime = ((TMActor) actor).getExecutionTime();
} else {
// Use the executionTime parameter from the port
// or the actor.
Parameter executionTime = (Parameter) event.receiver()
.getContainer().getAttribute("executionTime");
// Actor starts to execute
if (executionTime == null) {
executionTime = (Parameter) ((NamedObj) actor)
.getAttribute("executionTime");
}
if (executionTime != null) {
processingTime = ((DoubleToken) executionTime
.getToken()).doubleValue();
}
}
if (processingTime == 0.0) {
if (_debugging) {
_debug(getName(), event.toString(),
" has processing time 0, so processed.");
}
// This event can be processed immediately.
_eventQueue.take();
actor.fire();
// Actor stops executing, i.e. finishing
_displaySchedule(((Nameable) actor).getName(),
getModelTime().getDoubleValue(),
ScheduleListener.TASK_SLEEPING);
_displaySchedule();
if (!actor.postfire()) {
_disableActor(actor);
}
} else {
// Really start a task with non-zero processing
// time.
event.setProcessingTime(processingTime);
if (_debugging) {
_debug("Set processing time ", event.toString());
}
// Start a new task.
// Now the behavior depend on whether the
// execution is preemptive.
_preemptive = ((BooleanToken) preemptive.getToken())
.booleanValue();
if (!_preemptive) {
event = (TMEvent) _eventQueue.take();
event.startProcessing();
// Set it priority to 0 so it won't
// be preempted.
event.setPriority(0);
_eventQueue.put(event);
} else {
event.startProcessing();
}
if (_debugging) {
_debug("Start processing ", event.toString());
}
_displaySchedule();
// Start one real time task a time.
break;
}
}
} else {
break;
}
}
// The event may be null, when the prefire() of the actor
// returns false for the last event in the queue.
// The event may have processing time < 0, in which case
// it is an event at the output boundary.
if ((event != null) && (event.processingTime() > 0)) {
// Check the finish processing time.
Time finishTime = getModelTime().add(event.processingTime());
if (_debugging) {
_debug("finishing time = " + finishTime);
}
if (finishTime.compareTo(_nextIterationTime) < 0) {
_nextIterationTime = finishTime;
}
}
if (_isEmbedded()