Program: 73402
Project: 73402
Buggy source:
/** 
 * Override the _transferOutputs() function. First, for tokens that are stored in the actuator event queue, send them to the outside of the platform if physical time has arrived. Second, compare current model time with simulated physical time. If physical time is smaller than current model time, then deadline has been missed. Throw an exception unless the port is annotated with ignoreDeadline. If the deadline has been missed and ignoreDeadline is true, or if the current model time is equal to the physical time, or if the port is annotated with transferImmediately, we send the tokens to the outside. If current model time has not arrived at the physical time, we put the token along with the destination port and channel into the actuator event queue, and call fireAt of the executive director so we could send it at a later physical time. <p> As described in the comment for this class, there are two versions of simulated physical time: oracle simulated physical time, and platform simulated physical time. The time at which an actuation event is sent to the output port uses the platform simulated physical time. </p>
 * @param port The port to transfer tokens to.
 * @return True if at least one data token is transferred.
 * @exception IllegalActionException If the port is not an opaqueinput port, if the super class throws it, if physical tag cannot be evaluated, or if the token cannot be sent to the inside.
 */
protected boolean _transferOutputs(IOPort port) throws IllegalActionException {
  if (!port.isOutput() || !port.isOpaque()) {
    throw new IllegalActionException(this,port,"String_Node_Str" + "String_Node_Str");
  }
  boolean result=false;
  Tag platformPhysicalTag=getPlatformPhysicalTag(platformTimeClock);
  int compare=0;
  while (true) {
    if (_realTimeOutputEventQueue.isEmpty()) {
      break;
    }
    RealTimeEvent tokenEvent=(RealTimeEvent)_realTimeOutputEventQueue.peek();
    compare=tokenEvent.deliveryTag.compareTo(platformPhysicalTag);
    if (compare > 0) {
      break;
    }
 else     if (compare == 0) {
      _realTimeOutputEventQueue.poll();
      tokenEvent.port.send(tokenEvent.channel,tokenEvent.token);
      if (_debugging) {
        _debug(getName(),"String_Node_Str" + tokenEvent.token + "String_Node_Str"+ tokenEvent.port.getName());
      }
      result=true;
    }
 else     if (compare < 0) {
      throw new IllegalActionException(tokenEvent.port,"String_Node_Str" + tokenEvent.deliveryTag.timestamp + "String_Node_Str"+ tokenEvent.deliveryTag.microstep+ "String_Node_Str"+ platformPhysicalTag.timestamp+ "String_Node_Str"+ platformPhysicalTag.microstep);
    }
  }
  Double actuatorDeviceDelay=_getDeviceDelay(port);
  Time deadline=_currentTime;
  if (actuatorDeviceDelay != null) {
    deadline=deadline.subtract(actuatorDeviceDelay);
  }
  compare=deadline.compareTo(platformPhysicalTag.timestamp);
  if (compare < 0 && !_ignoreDeadline(port)) {
    for (int i=0; i < port.getWidthInside(); i++) {
      if (port.hasTokenInside(i)) {
        throw new IllegalActionException(port,"String_Node_Str" + _currentTime + "String_Node_Str"+ platformPhysicalTag.timestamp);
      }
    }
  }
 else   if (compare == 0 || _transferImmediately(port) || (compare < 0 && _ignoreDeadline(port))) {
    while (true) {
      if (!super._transferOutputs(port)) {
        break;
      }
 else {
        result=true;
      }
    }
  }
 else {
    assert(compare > 0);
    for (int i=0; i < port.getWidthInside(); i++) {
      try {
        if (port.hasTokenInside(i)) {
          Token t=port.getInside(i);
          RealTimeEvent tokenEvent=new RealTimeEvent(port,i,t,new Tag(_currentTime,_microstep),null);
          _realTimeOutputEventQueue.add(tokenEvent);
          _fireAtPlatformTime(_currentTime,platformTimeClock);
        }
      }
 catch (      NoTokenException ex) {
        throw new InternalErrorException(this,ex,null);
      }
    }
  }
  return result;
}

Fixed version (ground truth):
/** 
 * Override the _transferOutputs() function. First, for tokens that are stored in the actuator event queue, send them to the outside of the platform if physical time has arrived. Second, compare current model time with simulated physical time. If physical time is smaller than current model time, then deadline has been missed. Throw an exception unless the port is annotated with ignoreDeadline. If the deadline has been missed and ignoreDeadline is true, or if the current model time is equal to the physical time, or if the port is annotated with transferImmediately, we send the tokens to the outside. If current model time has not arrived at the physical time, we put the token along with the destination port and channel into the actuator event queue, and call fireAt of the executive director so we could send it at a later physical time. <p> As described in the comment for this class, there are two versions of simulated physical time: oracle simulated physical time, and platform simulated physical time. The time at which an actuation event is sent to the output port uses the platform simulated physical time. </p>
 * @param port The port to transfer tokens to.
 * @return True if at least one data token is transferred.
 * @exception IllegalActionException If the port is not an opaqueinput port, if the super class throws it, if physical tag cannot be evaluated, or if the token cannot be sent to the inside.
 */
protected boolean _transferOutputs(IOPort port) throws IllegalActionException {
  if (!port.isOutput() || !port.isOpaque()) {
    throw new IllegalActionException(this,port,"String_Node_Str" + "String_Node_Str");
  }
  boolean result=false;
  Tag platformPhysicalTag=getPlatformPhysicalTag(platformTimeClock);
  int compare=0;
  while (true) {
    if (_realTimeOutputEventQueue.isEmpty()) {
      break;
    }
    RealTimeEvent tokenEvent=(RealTimeEvent)_realTimeOutputEventQueue.peek();
    compare=tokenEvent.deliveryTag.compareTo(platformPhysicalTag);
    if (compare > 0) {
      if (tokenEvent.deliveryTag.timestamp.equals(platformPhysicalTag.timestamp)) {
        (((Actor)getContainer()).getExecutiveDirector()).fireAtCurrentTime((Actor)getContainer());
      }
      break;
    }
 else     if (compare == 0) {
      _realTimeOutputEventQueue.poll();
      tokenEvent.port.send(tokenEvent.channel,tokenEvent.token);
      if (_debugging) {
        _debug(getName(),"String_Node_Str" + tokenEvent.token + "String_Node_Str"+ tokenEvent.port.getName());
      }
      result=true;
    }
 else     if (compare < 0) {
      throw new IllegalActionException(tokenEvent.port,"String_Node_Str" + tokenEvent.deliveryTag.timestamp + "String_Node_Str"+ tokenEvent.deliveryTag.microstep+ "String_Node_Str"+ platformPhysicalTag.timestamp+ "String_Node_Str"+ platformPhysicalTag.microstep);
    }
  }
  Double actuatorDeviceDelay=_getDeviceDelay(port);
  Time deadline=_currentTime;
  if (actuatorDeviceDelay != null) {
    deadline=deadline.subtract(actuatorDeviceDelay);
  }
  compare=deadline.compareTo(platformPhysicalTag.timestamp);
  if (compare < 0 && !_ignoreDeadline(port)) {
    for (int i=0; i < port.getWidthInside(); i++) {
      if (port.hasTokenInside(i)) {
        throw new IllegalActionException(port,"String_Node_Str" + _currentTime + "String_Node_Str"+ platformPhysicalTag.timestamp);
      }
    }
  }
 else   if (compare == 0 || _transferImmediately(port) || (compare < 0 && _ignoreDeadline(port))) {
    while (true) {
      if (!super._transferOutputs(port)) {
        break;
      }
 else {
        result=true;
      }
    }
  }
 else {
    assert(compare > 0);
    for (int i=0; i < port.getWidthInside(); i++) {
      try {
        if (port.hasTokenInside(i)) {
          Token t=port.getInside(i);
          RealTimeEvent tokenEvent=new RealTimeEvent(port,i,t,new Tag(_currentTime,_microstep),null);
          _realTimeOutputEventQueue.add(tokenEvent);
          _fireAtPlatformTime(_currentTime,platformTimeClock);
        }
      }
 catch (      NoTokenException ex) {
        throw new InternalErrorException(this,ex,null);
      }
    }
  }
  return result;
}