Program: 74004
Project: 74004
Buggy source:
/** 
 * Causality analysis that happens at the preinitialization phase. The goal is to annotate each port with a minDelay parameter, which is the offset used for safe to process analysis. <p> Start from each input port that is connected to the outside of the platform (These input ports indicate sensors and network interfaces, call them startPorts), and traverse the graph until we reach the output port connected to the outside of the platform (actuators). For each input port in between, annotate it with a minDelay parameter. This parameter is an array of doubles, where each double corresponds to the minimum delay offset for a particular channel of that port. This minimum delay offset is used for the safe to process analysis. </p> FIXME: currently this algorithm does not support transparent composite actors, but it should.
 * @exception IllegalActionException
 */
protected void _calculateMinDelayOffsets() throws IllegalActionException {
  _clearMinDelayOffsets();
  Map inputModelTimeDelays=new HashMap<IOPort,Map<Integer,SuperdenseDependency>>();
  HashMap portDelays=new HashMap<IOPort,SuperdenseDependency>();
  for (  Actor actor : (List<Actor>)(((TypedCompositeActor)getContainer()).deepEntityList())) {
    for (    TypedIOPort inputPort : (List<TypedIOPort>)(actor.inputPortList())) {
      portDelays.put(inputPort,SuperdenseDependency.OPLUS_IDENTITY);
    }
    for (    TypedIOPort outputPort : (List<TypedIOPort>)(actor.outputPortList())) {
      portDelays.put(outputPort,SuperdenseDependency.OPLUS_IDENTITY);
    }
  }
  for (  TypedIOPort inputPort : (List<TypedIOPort>)(((Actor)getContainer()).inputPortList())) {
    SuperdenseDependency startDelay;
    if (_isNetworkPort(inputPort)) {
      startDelay=SuperdenseDependency.valueOf(_getNetworkDelay(inputPort),0);
    }
 else {
      startDelay=SuperdenseDependency.valueOf(-_getRealTimeDelay(inputPort),0);
    }
    portDelays.put(inputPort,startDelay);
  }
  for (  TypedIOPort startPort : (List<TypedIOPort>)(((TypedCompositeActor)getContainer()).inputPortList())) {
    HashMap localPortDelays=new HashMap<IOPort,SuperdenseDependency>(portDelays);
    PriorityQueue distQueue=new PriorityQueue<PortDependency>();
    distQueue.add(new PortDependency(startPort,(SuperdenseDependency)localPortDelays.get(startPort)));
    while (!distQueue.isEmpty()) {
      PortDependency portDependency=(PortDependency)distQueue.remove();
      IOPort port=(IOPort)portDependency.port;
      SuperdenseDependency prevDependency=(SuperdenseDependency)portDependency.dependency;
      Actor actor=(Actor)port.getContainer();
      if (port.isInput() && port.isOutput()) {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str");
      }
      if (actor != getContainer()) {
        if (port.isInput()) {
          Collection<IOPort> outputs=_finiteDependentPorts(port);
          for (          IOPort outputPort : outputs) {
            SuperdenseDependency minimumDelay=(SuperdenseDependency)_getDependency(port,outputPort);
            SuperdenseDependency modelTime=(SuperdenseDependency)prevDependency.oTimes(minimumDelay);
            if (((SuperdenseDependency)localPortDelays.get(outputPort)).compareTo(modelTime) > 0) {
              localPortDelays.put(outputPort,modelTime);
              distQueue.add(new PortDependency(outputPort,modelTime));
            }
          }
        }
 else {
          Receiver[][] remoteReceivers=port.getRemoteReceivers();
          for (int i=0; i < remoteReceivers.length; i++) {
            for (int j=0; j < remoteReceivers[i].length; j++) {
              IOPort sinkPort=remoteReceivers[i][j].getContainer();
              int channel=sinkPort.getChannelForReceiver(remoteReceivers[i][j]);
              if (sinkPort.getContainer() != getContainer()) {
                Map<Integer,SuperdenseDependency> channelDependency=(Map<Integer,SuperdenseDependency>)inputModelTimeDelays.get(sinkPort);
                if (channelDependency == null) {
                  channelDependency=new HashMap<Integer,SuperdenseDependency>();
                }
                channelDependency.put(Integer.valueOf(channel),prevDependency);
                inputModelTimeDelays.put(sinkPort,channelDependency);
                if (((SuperdenseDependency)localPortDelays.get(sinkPort)).compareTo(prevDependency) > 0) {
                  localPortDelays.put(sinkPort,prevDependency);
                  distQueue.add(new PortDependency(sinkPort,prevDependency));
                }
              }
            }
          }
        }
      }
 else       if (port == startPort) {
        Receiver[][] deepReceivers=port.deepGetReceivers();
        for (int i=0; i < deepReceivers.length; i++) {
          for (int j=0; j < deepReceivers[i].length; j++) {
            IOPort sinkPort=deepReceivers[i][j].getContainer();
            int channel=sinkPort.getChannelForReceiver(deepReceivers[i][j]);
            if (sinkPort.getContainer() != getContainer()) {
              Map<Integer,SuperdenseDependency> channelDependency=(Map<Integer,SuperdenseDependency>)inputModelTimeDelays.get(sinkPort);
              if (channelDependency == null) {
                channelDependency=new HashMap<Integer,SuperdenseDependency>();
              }
              channelDependency.put(Integer.valueOf(channel),prevDependency);
              inputModelTimeDelays.put(sinkPort,channelDependency);
              if (((SuperdenseDependency)localPortDelays.get(sinkPort)).compareTo(prevDependency) > 0) {
                localPortDelays.put(sinkPort,prevDependency);
                distQueue.add(new PortDependency(sinkPort,prevDependency));
              }
            }
          }
        }
      }
    }
    portDelays=localPortDelays;
  }
  for (  IOPort inputPort : (Set<IOPort>)inputModelTimeDelays.keySet()) {
    Map<Integer,SuperdenseDependency> channelDependency=(Map<Integer,SuperdenseDependency>)inputModelTimeDelays.get(inputPort);
    double[] minDelays=new double[channelDependency.size()];
    for (    Integer portChannelMinDelay : channelDependency.keySet()) {
      minDelays[portChannelMinDelay.intValue()]=_calculateMinDelayForPortChannel(inputPort,portChannelMinDelay,inputModelTimeDelays);
    }
    _setMinDelay(inputPort,minDelays);
  }
}

Fixed version (ground truth):
/** 
 * Causality analysis that happens at the preinitialization phase. The goal is to annotate each port with a minDelay parameter, which is the offset used for safe to process analysis. <p> Start from each input port that is connected to the outside of the platform (These input ports indicate sensors and network interfaces, call them startPorts), and traverse the graph until we reach the output port connected to the outside of the platform (actuators). For each input port in between, annotate it with a minDelay parameter. This parameter is an array of doubles, where each double corresponds to the minimum delay offset for a particular channel of that port. This minimum delay offset is used for the safe to process analysis. </p> FIXME: currently this algorithm does not support transparent composite actors, but it should.
 * @exception IllegalActionException
 */
protected void _calculateMinDelayOffsets() throws IllegalActionException {
  _clearMinDelayOffsets();
  Map inputModelTimeDelays=new HashMap<IOPort,Map<Integer,SuperdenseDependency>>();
  HashMap portDelays=new HashMap<IOPort,SuperdenseDependency>();
  for (  Actor actor : (List<Actor>)(((TypedCompositeActor)getContainer()).deepEntityList())) {
    for (    TypedIOPort inputPort : (List<TypedIOPort>)(actor.inputPortList())) {
      portDelays.put(inputPort,SuperdenseDependency.OPLUS_IDENTITY);
    }
    for (    TypedIOPort outputPort : (List<TypedIOPort>)(actor.outputPortList())) {
      portDelays.put(outputPort,SuperdenseDependency.OPLUS_IDENTITY);
    }
  }
  for (  TypedIOPort inputPort : (List<TypedIOPort>)(((Actor)getContainer()).inputPortList())) {
    SuperdenseDependency startDelay;
    if (_isNetworkPort(inputPort)) {
      startDelay=SuperdenseDependency.valueOf(_getNetworkDelay(inputPort),0);
    }
 else {
      startDelay=SuperdenseDependency.valueOf(-_getRealTimeDelay(inputPort),0);
    }
    portDelays.put(inputPort,startDelay);
  }
  for (  TypedIOPort startPort : (List<TypedIOPort>)(((TypedCompositeActor)getContainer()).inputPortList())) {
    HashMap localPortDelays=new HashMap<IOPort,SuperdenseDependency>(portDelays);
    PriorityQueue distQueue=new PriorityQueue<PortDependency>();
    distQueue.add(new PortDependency(startPort,(SuperdenseDependency)localPortDelays.get(startPort)));
    while (!distQueue.isEmpty()) {
      PortDependency portDependency=(PortDependency)distQueue.remove();
      IOPort port=(IOPort)portDependency.port;
      SuperdenseDependency prevDependency=(SuperdenseDependency)portDependency.dependency;
      Actor actor=(Actor)port.getContainer();
      if (port.isInput() && port.isOutput()) {
        throw new IllegalActionException("String_Node_Str" + "String_Node_Str");
      }
      if (actor != getContainer()) {
        if (port.isInput()) {
          Collection<IOPort> outputs=_finiteDependentPorts(port);
          for (          IOPort outputPort : outputs) {
            SuperdenseDependency minimumDelay=(SuperdenseDependency)_getDependency(port,outputPort);
            SuperdenseDependency modelTime=(SuperdenseDependency)prevDependency.oTimes(minimumDelay);
            if (((SuperdenseDependency)localPortDelays.get(outputPort)).compareTo(modelTime) > 0) {
              localPortDelays.put(outputPort,modelTime);
              distQueue.add(new PortDependency(outputPort,modelTime));
            }
          }
        }
 else {
          Receiver[][] remoteReceivers=port.getRemoteReceivers();
          if (remoteReceivers != null) {
            for (int i=0; i < remoteReceivers.length; i++) {
              if (remoteReceivers[0] != null) {
                for (int j=0; j < remoteReceivers[i].length; j++) {
                  IOPort sinkPort=remoteReceivers[i][j].getContainer();
                  int channel=sinkPort.getChannelForReceiver(remoteReceivers[i][j]);
                  if (sinkPort.getContainer() != getContainer()) {
                    Map<Integer,SuperdenseDependency> channelDependency=(Map<Integer,SuperdenseDependency>)inputModelTimeDelays.get(sinkPort);
                    if (channelDependency == null) {
                      channelDependency=new HashMap<Integer,SuperdenseDependency>();
                    }
                    channelDependency.put(Integer.valueOf(channel),prevDependency);
                    inputModelTimeDelays.put(sinkPort,channelDependency);
                    if (((SuperdenseDependency)localPortDelays.get(sinkPort)).compareTo(prevDependency) > 0) {
                      localPortDelays.put(sinkPort,prevDependency);
                      distQueue.add(new PortDependency(sinkPort,prevDependency));
                    }
                  }
                }
              }
            }
          }
        }
      }
 else       if (port == startPort) {
        Receiver[][] deepReceivers=port.deepGetReceivers();
        for (int i=0; i < deepReceivers.length; i++) {
          for (int j=0; j < deepReceivers[i].length; j++) {
            IOPort sinkPort=deepReceivers[i][j].getContainer();
            int channel=sinkPort.getChannelForReceiver(deepReceivers[i][j]);
            if (sinkPort.getContainer() != getContainer()) {
              Map<Integer,SuperdenseDependency> channelDependency=(Map<Integer,SuperdenseDependency>)inputModelTimeDelays.get(sinkPort);
              if (channelDependency == null) {
                channelDependency=new HashMap<Integer,SuperdenseDependency>();
              }
              channelDependency.put(Integer.valueOf(channel),prevDependency);
              inputModelTimeDelays.put(sinkPort,channelDependency);
              if (((SuperdenseDependency)localPortDelays.get(sinkPort)).compareTo(prevDependency) > 0) {
                localPortDelays.put(sinkPort,prevDependency);
                distQueue.add(new PortDependency(sinkPort,prevDependency));
              }
            }
          }
        }
      }
    }
    portDelays=localPortDelays;
  }
  for (  IOPort inputPort : (Set<IOPort>)inputModelTimeDelays.keySet()) {
    Map<Integer,SuperdenseDependency> channelDependency=(Map<Integer,SuperdenseDependency>)inputModelTimeDelays.get(inputPort);
    double[] minDelays=new double[channelDependency.size()];
    for (    Integer portChannelMinDelay : channelDependency.keySet()) {
      minDelays[portChannelMinDelay.intValue()]=_calculateMinDelayForPortChannel(inputPort,portChannelMinDelay,inputModelTimeDelays);
    }
    _setMinDelay(inputPort,minDelays);
  }
}