Program: 73481
Project: 73481
Buggy source:
/** 
 * Return the actor to fire in this iteration, or null if no actor should be fired. This method performs the simulation of execution time, as described below. Execution times are assumed to be in oracle simulated physical time, not platform simulated physical time. The difference between these two times are described in the comment of this class. In this base class, this method first checks whether the top event from the event queue is destined for an actuator. If it is, then we check if physical time has reached the timestamp of the actuation event. If it has, then we fire the actuator. If it has not, then we take the actuator event from the event queue and put it onto the _realTimeEventQueue, and call fireAt() of the executive director. We then check if a real-time event should be processed by looking at the top event of the _realTimeEventQueue. If there is one that should be fired, that actor is returned for firing. If not, we go on and considers two cases, depending whether there is an actor currently executing, as follows: <p> <b>Case 1</b>: If there is no actor currently executing, then this method checks the event queue and returns null if it is empty. If it is not empty, it checks the destination actor of the earliest event on the event queue, and if it has a non-zero execution time, then it pushes it onto the currently executing stack and returns null. Otherwise, if the execution time of the actor is zero, it sets the current model time to the time stamp of that earliest event and returns that actor. <p> <b>Case 2</b>: If there is an actor currently executing, then this method checks whether it has a remaining execution time of zero. If it does, then it returns the currently executing actor. If it does not, then it checks whether the earliest event on the event queue should preempt it (by invoking _preemptExecutingActor()), and if so, checks the destination actor of that event and removes the event from the event queue. If that destination actor has an execution time of zero, then it sets the current model time to the time stamp of that event, and returns that actor. Else if the destination actor has an execution time of bigger than zero, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null. If there is no event on the event queue or that event should not preempt the currently executing actor, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null.
 * @return The next actor to be fired, which can be null.
 * @exception IllegalActionException If event queue is not ready, oran event is missed, or time is set backwards, or if the enclosing director does not respect the fireAt call. <p> Also, when an actor is fired, not only is the top event processed, all events in the event queue are also checked to see whether they have the same actor as destination, and they have the same timestamp as the top event. Those that do are also taken out of the event queue and processed. <p> Finally, in any of the following situations: a sensor interrupt has occurred, a timed interrupt has occurred, or an actor has finished firing; the scheduler must run to decide whether the next event should be processed. Since the Ptides simulator simulates the passage of physical time, we also simulate the overhead for the scheduler to make its decision. The parameter:  {@link #schedulerExecutionTime} indicates this time.Note, when sensor and timed interrupts occurs, the currently executing event will be preempted to perform the scheduling overhead. <p> If at some simulated physical time, a sensor interrupt occurred, at the same time, a previous event finished execution, then we always assume the sensor interruption occurred first, and the event should be put into the event queue before the finished event is dealt with.
 * @see #_preemptExecutingActor()
 */
protected Actor _getNextActorToFire() throws IllegalActionException {
  Tag executionPhysicalTag=getPlatformPhysicalTag(EXECUTION_TIMER);
  Actor container=(Actor)getContainer();
  Director executiveDirector=container.getExecutiveDirector();
  if (_schedulerStillRunning()) {
    return null;
  }
  if (_inputEventInterruptOccurred) {
    _inputEventInterruptOccurred=false;
    if (_startScheduler()) {
      _resetExecutionTimeForPreemptedEvent();
      _physicalTimeExecutionStarted=null;
      return null;
    }
  }
  if (_timedInterruptOccurred()) {
    if (_startScheduler()) {
      _resetExecutionTimeForPreemptedEvent();
      _physicalTimeExecutionStarted=null;
      return null;
    }
  }
  if (_scheduleNewEvent) {
    _scheduleNewEvent=false;
    if (_startScheduler()) {
      _resetExecutionTimeForPreemptedEvent();
      _physicalTimeExecutionStarted=null;
      return null;
    }
  }
  if (!_currentlyExecutingStack.isEmpty()) {
    if (_physicalTimeExecutionStarted == null) {
      _physicalTimeExecutionStarted=executionPhysicalTag.timestamp;
    }
    DoubleTimedEvent currentEventList=(DoubleTimedEvent)_currentlyExecutingStack.peek();
    Time remainingExecutionTime=currentEventList.remainingExecutionTime;
    Time finishTime=_physicalTimeExecutionStarted.add(remainingExecutionTime);
    int comparison=finishTime.compareTo(executionPhysicalTag.timestamp);
    if (comparison < 0) {
      throw new IllegalActionException(this,_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),"String_Node_Str");
    }
 else     if (comparison == 0) {
      setTag(currentEventList.timeStamp,currentEventList.microstep);
      _currentlyExecutingStack.pop();
      _physicalTimeExecutionStarted=executionPhysicalTag.timestamp;
      if (_debugging) {
        _debug("String_Node_Str" + _getActorFromEventList((List<PtidesEvent>)currentEventList.contents).getName(getContainer()) + "String_Node_Str"+ executionPhysicalTag.timestamp);
      }
      _setIcon(_getIdleIcon(),false);
      _clearHighlight(_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),false);
      _lastExecutingActor=null;
      executiveDirector.fireAtCurrentTime((Actor)container);
      _lastActorFired=_getActorFromEventList((List<PtidesEvent>)currentEventList.contents);
      if (!(_lastActorFired instanceof SensorInputDevice)) {
        _scheduleNewEvent=true;
      }
      return _lastActorFired;
    }
 else {
      _fireAtPlatformTime(finishTime,EXECUTION_TIMER);
      if (_eventQueue.isEmpty() || !_preemptExecutingActor()) {
        return null;
      }
    }
  }
  if (_eventQueue.isEmpty()) {
    _setIcon(_getIdleIcon(),false);
    return null;
  }
  PtidesEvent eventFromQueue=_getNextSafeEvent();
  if (eventFromQueue == null) {
    return null;
  }
  Time timeStampOfEventFromQueue=eventFromQueue.timeStamp();
  int microstepOfEventFromQueue=eventFromQueue.microstep();
  _trackLastTagConsumedByActor(eventFromQueue);
  List<PtidesEvent> eventsToProcess=_takeAllSameTagEventsFromQueue(eventFromQueue);
  Actor actorToFire=_getNextActorToFireForTheseEvents(eventsToProcess);
  IOPort ioPort=eventFromQueue.ioPort();
  if (ioPort == null) {
    List<IOPort> inPortList=eventFromQueue.actor().inputPortList();
    if (inPortList.size() > 0) {
      ioPort=inPortList.get(0);
    }
  }
  _saveEventInformation(eventsToProcess);
  Time executionTime=new Time(this,_getExecutionTime(ioPort,actorToFire));
  if (executionTime.compareTo(_zero) == 0) {
    setTag(timeStampOfEventFromQueue,microstepOfEventFromQueue);
    executiveDirector.fireAtCurrentTime((Actor)container);
    _lastActorFired=actorToFire;
    if (!(_lastActorFired instanceof SensorInputDevice)) {
      _scheduleNewEvent=true;
    }
    return actorToFire;
  }
 else {
    Time expectedCompletionTime=executionPhysicalTag.timestamp.add(executionTime);
    _fireAtPlatformTime(expectedCompletionTime,EXECUTION_TIMER);
    _resetExecutionTimeForPreemptedEvent();
    _currentlyExecutingStack.push(new DoubleTimedEvent(timeStampOfEventFromQueue,microstepOfEventFromQueue,eventsToProcess,executionTime));
    _physicalTimeExecutionStarted=executionPhysicalTag.timestamp;
    if (_debugging) {
      _debug("String_Node_Str" + actorToFire.toString() + "String_Node_Str"+ executionPhysicalTag.timestamp);
    }
    _setIcon(_getExecutingIcon(actorToFire),false);
    _lastExecutingActor=actorToFire;
    return null;
  }
}

Fixed version (ground truth):
/** 
 * Return the actor to fire in this iteration, or null if no actor should be fired. This method performs the simulation of execution time, as described below. Execution times are assumed to be in oracle simulated physical time, not platform simulated physical time. The difference between these two times are described in the comment of this class. In this base class, this method first checks whether the top event from the event queue is destined for an actuator. If it is, then we check if physical time has reached the timestamp of the actuation event. If it has, then we fire the actuator. If it has not, then we take the actuator event from the event queue and put it onto the _realTimeEventQueue, and call fireAt() of the executive director. We then check if a real-time event should be processed by looking at the top event of the _realTimeEventQueue. If there is one that should be fired, that actor is returned for firing. If not, we go on and considers two cases, depending whether there is an actor currently executing, as follows: <p> <b>Case 1</b>: If there is no actor currently executing, then this method checks the event queue and returns null if it is empty. If it is not empty, it checks the destination actor of the earliest event on the event queue, and if it has a non-zero execution time, then it pushes it onto the currently executing stack and returns null. Otherwise, if the execution time of the actor is zero, it sets the current model time to the time stamp of that earliest event and returns that actor. <p> <b>Case 2</b>: If there is an actor currently executing, then this method checks whether it has a remaining execution time of zero. If it does, then it returns the currently executing actor. If it does not, then it checks whether the earliest event on the event queue should preempt it (by invoking _preemptExecutingActor()), and if so, checks the destination actor of that event and removes the event from the event queue. If that destination actor has an execution time of zero, then it sets the current model time to the time stamp of that event, and returns that actor. Else if the destination actor has an execution time of bigger than zero, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null. If there is no event on the event queue or that event should not preempt the currently executing actor, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null.
 * @return The next actor to be fired, which can be null.
 * @exception IllegalActionException If event queue is not ready, oran event is missed, or time is set backwards, or if the enclosing director does not respect the fireAt call. <p> Also, when an actor is fired, not only is the top event processed, all events in the event queue are also checked to see whether they have the same actor as destination, and they have the same timestamp as the top event. Those that do are also taken out of the event queue and processed. <p> Finally, in any of the following situations: a sensor interrupt has occurred, a timed interrupt has occurred, or an actor has finished firing; the scheduler must run to decide whether the next event should be processed. Since the Ptides simulator simulates the passage of physical time, we also simulate the overhead for the scheduler to make its decision. The parameter:  {@link #schedulerExecutionTime} indicates this time.Note, when sensor and timed interrupts occurs, the currently executing event will be preempted to perform the scheduling overhead. <p> If at some simulated physical time, a sensor interrupt occurred, at the same time, a previous event finished execution, then we always assume the sensor interruption occurred first, and the event should be put into the event queue before the finished event is dealt with.
 * @see #_preemptExecutingActor()
 */
protected Actor _getNextActorToFire() throws IllegalActionException {
  Tag executionPhysicalTag=getPlatformPhysicalTag(EXECUTION_TIMER);
  Actor container=(Actor)getContainer();
  Director executiveDirector=container.getExecutiveDirector();
  if (_ignoreThisFireAtTime(_ignoredExecutionFireAtTimes) || _ignoreThisFireAtTime(_ignoredPlatformFireAtTimes)) {
    return null;
  }
  if (_schedulerStillRunning()) {
    return null;
  }
  if (_inputEventInterruptOccurred) {
    _inputEventInterruptOccurred=false;
    if (_startScheduler()) {
      _resetExecutionTimeForPreemptedEvent();
      _physicalTimeExecutionStarted=null;
      return null;
    }
  }
  if (_timedInterruptOccurred()) {
    if (_startScheduler()) {
      _resetExecutionTimeForPreemptedEvent();
      _physicalTimeExecutionStarted=null;
      return null;
    }
  }
  if (_scheduleNewEvent) {
    _scheduleNewEvent=false;
    if (_startScheduler()) {
      _resetExecutionTimeForPreemptedEvent();
      _physicalTimeExecutionStarted=null;
      return null;
    }
  }
  if (!_currentlyExecutingStack.isEmpty()) {
    if (_physicalTimeExecutionStarted == null) {
      _physicalTimeExecutionStarted=executionPhysicalTag.timestamp;
    }
    DoubleTimedEvent currentEventList=(DoubleTimedEvent)_currentlyExecutingStack.peek();
    Time remainingExecutionTime=currentEventList.remainingExecutionTime;
    Time finishTime=_physicalTimeExecutionStarted.add(remainingExecutionTime);
    int comparison=finishTime.compareTo(executionPhysicalTag.timestamp);
    if (comparison < 0) {
      throw new IllegalActionException(this,_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),"String_Node_Str");
    }
 else     if (comparison == 0) {
      setTag(currentEventList.timeStamp,currentEventList.microstep);
      _currentlyExecutingStack.pop();
      _physicalTimeExecutionStarted=executionPhysicalTag.timestamp;
      if (_debugging) {
        _debug("String_Node_Str" + _getActorFromEventList((List<PtidesEvent>)currentEventList.contents).getName(getContainer()) + "String_Node_Str"+ executionPhysicalTag.timestamp);
      }
      _setIcon(_getIdleIcon(),false);
      _clearHighlight(_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),false);
      _lastExecutingActor=null;
      executiveDirector.fireAtCurrentTime((Actor)container);
      _lastActorFired=_getActorFromEventList((List<PtidesEvent>)currentEventList.contents);
      if (!(_lastActorFired instanceof SensorInputDevice)) {
        _scheduleNewEvent=true;
      }
      return _lastActorFired;
    }
 else {
      _fireAtPlatformTime(finishTime,EXECUTION_TIMER);
      if (_eventQueue.isEmpty() || !_preemptExecutingActor()) {
        return null;
      }
    }
  }
  if (_eventQueue.isEmpty()) {
    _setIcon(_getIdleIcon(),false);
    return null;
  }
  PtidesEvent eventFromQueue=_getNextSafeEvent();
  if (eventFromQueue == null) {
    return null;
  }
  Time timeStampOfEventFromQueue=eventFromQueue.timeStamp();
  int microstepOfEventFromQueue=eventFromQueue.microstep();
  _trackLastTagConsumedByActor(eventFromQueue);
  List<PtidesEvent> eventsToProcess=_takeAllSameTagEventsFromQueue(eventFromQueue);
  Actor actorToFire=_getNextActorToFireForTheseEvents(eventsToProcess);
  IOPort ioPort=eventFromQueue.ioPort();
  if (ioPort == null) {
    List<IOPort> inPortList=eventFromQueue.actor().inputPortList();
    if (inPortList.size() > 0) {
      ioPort=inPortList.get(0);
    }
  }
  _saveEventInformation(eventsToProcess);
  Time executionTime=new Time(this,_getExecutionTime(ioPort,actorToFire));
  if (executionTime.compareTo(_zero) == 0) {
    setTag(timeStampOfEventFromQueue,microstepOfEventFromQueue);
    executiveDirector.fireAtCurrentTime((Actor)container);
    _lastActorFired=actorToFire;
    if (!(_lastActorFired instanceof SensorInputDevice)) {
      _scheduleNewEvent=true;
    }
    return actorToFire;
  }
 else {
    Time expectedCompletionTime=executionPhysicalTag.timestamp.add(executionTime);
    _fireAtPlatformTime(expectedCompletionTime,EXECUTION_TIMER);
    _resetExecutionTimeForPreemptedEvent();
    _currentlyExecutingStack.push(new DoubleTimedEvent(timeStampOfEventFromQueue,microstepOfEventFromQueue,eventsToProcess,executionTime));
    _physicalTimeExecutionStarted=executionPhysicalTag.timestamp;
    if (_debugging) {
      _debug("String_Node_Str" + actorToFire.toString() + "String_Node_Str"+ executionPhysicalTag.timestamp);
    }
    _setIcon(_getExecutingIcon(actorToFire),false);
    _lastExecutingActor=actorToFire;
    return null;
  }
}