Program: 76403
Project: 76403
Buggy source:
/** 
 * Create a schedule for a set of UnscheduledActors.  Given a valid firing vector, simulate the scheduling of the actors until the end of one synchronous dataflow iteration. Each actor will appear in the schedule exactly the number of times that minimally solves the balance equations and in an order where each actor has sufficient tokens on its inputs to fire.   Note that no claim is made that this is an optimal solution in any other sense. FIXME: This method destroys the firing vector.  This is not nice.
 * @param UnscheduledActors The Actors that need to be scheduled.
 * @return A CircularList of the Actors in the order they should fire.
 * @exception InvalidStateException If the algorithm encounters an SDFgraph that is not consistent with the firing vector, or detects an inconsistent internal state.
 */
private CircularList _scheduleConnectedActors(CircularList actorList){
  CircularList readyToScheduleActorList=new CircularList();
  CircularList newSchedule=new CircularList();
  boolean done=false;
  LLMap waitingTokens=new LLMap();
  CircularList unscheduledActorList=new CircularList();
  unscheduledActorList.appendElements(actorList.elements());
  Enumeration schedulableEntities=actorList.elements();
  try {
    while (schedulableEntities.hasMoreElements()) {
      Actor a=(Actor)schedulableEntities.nextElement();
      Enumeration ainputports=a.inputPorts();
      while (ainputports.hasMoreElements()) {
        IOPort ainputport=(IOPort)ainputports.nextElement();
        int[] tokencount=new int[ainputport.getWidth()];
        for (int channel=0; channel < tokencount.length; channel++)         tokencount[channel]=0;
        waitingTokens.putAt(ainputport,tokencount);
        Enumeration crelations=ainputport.linkedRelations();
        int channelNumber=0;
        while (crelations.hasMoreElements()) {
          IORelation crelation=(IORelation)crelations.nextElement();
          Enumeration cports=crelation.linkedSourcePorts();
          IOPort cport=(IOPort)cports.nextElement();
          if (cports.hasMoreElements())           throw new IllegalActionException(crelation,cport,"String_Node_Str" + "String_Node_Str");
          ComponentEntity cactor=(ComponentEntity)cport.getContainer();
          int rate=_getTokenInitProduction(cport);
          if (rate > 0) {
            for (int j=0; j < crelation.getWidth(); j++)             tokencount[channelNumber++]+=_getTokenProductionRate(cport);
          }
        }
      }
      int inputCount=_countUnfulfilledInputs(a,actorList,waitingTokens);
      if (inputCount == 0)       readyToScheduleActorList.insertFirst((ComponentEntity)a);
      _debug("String_Node_Str" + ((ComponentEntity)a).getName() + "String_Node_Str"+ (new Integer(inputCount)).toString()+ "String_Node_Str");
    }
    while (!done) {
      _debug("String_Node_Str");
      _debug(waitingTokens.toString());
      _debug("String_Node_Str");
      Enumeration actorsLeft=readyToScheduleActorList.elements();
      while (actorsLeft.hasMoreElements()) {
        Entity e=(Entity)actorsLeft.nextElement();
        _debug(e.getFullName());
      }
      ComponentEntity currentActor=(ComponentEntity)readyToScheduleActorList.at(0);
      readyToScheduleActorList.removeAt(0);
      _debug("String_Node_Str" + currentActor.getName());
      _simulateInputConsumption(currentActor,waitingTokens);
      newSchedule.insertLast(currentActor);
      Enumeration aOutputPorts=((Actor)currentActor).outputPorts();
      while (aOutputPorts.hasMoreElements()) {
        IOPort aOutputPort=(IOPort)aOutputPorts.nextElement();
        Integer createdTokens=new Integer(_getTokenProductionRate(aOutputPort));
        _simulateTokensCreated(aOutputPort,actorList,readyToScheduleActorList,waitingTokens);
      }
      int firingsRemaining=_getFiringCount(currentActor);
      firingsRemaining-=1;
      _setFiringCount(currentActor,firingsRemaining);
      _debug(currentActor.getName() + "String_Node_Str" + firingsRemaining+ "String_Node_Str");
      if (firingsRemaining < 0)       throw new IllegalStateException("String_Node_Str" + "String_Node_Str" + "String_Node_Str");
 else {
        if (firingsRemaining == 0) {
          unscheduledActorList.removeOneOf(currentActor);
        }
 else {
          int inputCount=_countUnfulfilledInputs((Actor)currentActor,unscheduledActorList,waitingTokens);
          if (inputCount < 1)           readyToScheduleActorList.insertLast(currentActor);
        }
      }
    }
  }
 catch (  NoSuchElementException e) {
    _debug("String_Node_Str");
    _debug(e.getMessage());
    done=true;
  }
catch (  IllegalActionException iae) {
    throw new InternalErrorException("String_Node_Str" + "String_Node_Str" + iae.getMessage());
  }
 finally {
    _debug("String_Node_Str");
  }
  Enumeration eschedule=newSchedule.elements();
  _debug("String_Node_Str");
  while (eschedule.hasMoreElements())   _debug(((ComponentEntity)eschedule.nextElement()).toString());
  return newSchedule;
}

Fixed version (ground truth):
/** 
 * Create a schedule for a set of UnscheduledActors.  Given a valid firing vector, simulate the scheduling of the actors until the end of one synchronous dataflow iteration. Each actor will appear in the schedule exactly the number of times that minimally solves the balance equations and in an order where each actor has sufficient tokens on its inputs to fire.   Note that no claim is made that this is an optimal solution in any other sense. FIXME: This method destroys the firing vector.  This is not nice.
 * @param UnscheduledActors The Actors that need to be scheduled.
 * @return A CircularList of the Actors in the order they should fire.
 * @exception InvalidStateException If the algorithm encounters an SDFgraph that is not consistent with the firing vector, or detects an inconsistent internal state.
 */
private CircularList _scheduleConnectedActors(CircularList actorList){
  CircularList readyToScheduleActorList=new CircularList();
  CircularList newSchedule=new CircularList();
  boolean done=false;
  LLMap waitingTokens=new LLMap();
  CircularList unscheduledActorList=new CircularList();
  unscheduledActorList.appendElements(actorList.elements());
  Enumeration schedulableEntities=actorList.elements();
  try {
    while (schedulableEntities.hasMoreElements()) {
      Actor a=(Actor)schedulableEntities.nextElement();
      Enumeration ainputports=a.inputPorts();
      while (ainputports.hasMoreElements()) {
        IOPort ainputport=(IOPort)ainputports.nextElement();
        int[] tokencount=new int[ainputport.getWidth()];
        for (int channel=0; channel < tokencount.length; channel++)         tokencount[channel]=0;
        waitingTokens.putAt(ainputport,tokencount);
        Enumeration crelations=ainputport.linkedRelations();
        int channelNumber=0;
        while (crelations.hasMoreElements()) {
          IORelation crelation=(IORelation)crelations.nextElement();
          Enumeration cports=crelation.linkedSourcePorts();
          IOPort cport=(IOPort)cports.nextElement();
          if (cports.hasMoreElements())           throw new IllegalActionException(crelation,cport,"String_Node_Str" + "String_Node_Str");
          ComponentEntity cactor=(ComponentEntity)cport.getContainer();
          int rate=_getTokenInitProduction(cport);
          if (rate > 0) {
            for (int j=0; j < crelation.getWidth(); j++)             tokencount[channelNumber++]+=_getTokenProductionRate(cport);
          }
        }
      }
      int inputCount=_countUnfulfilledInputs(a,actorList,waitingTokens);
      if (inputCount == 0)       readyToScheduleActorList.insertFirst((ComponentEntity)a);
      _debug("String_Node_Str" + ((ComponentEntity)a).getName() + "String_Node_Str"+ (new Integer(inputCount)).toString()+ "String_Node_Str");
    }
    while (!done) {
      _debug("String_Node_Str");
      _debug(waitingTokens.toString());
      _debug("String_Node_Str");
      Enumeration actorsLeft=readyToScheduleActorList.elements();
      while (actorsLeft.hasMoreElements()) {
        Entity e=(Entity)actorsLeft.nextElement();
        _debug(e.getFullName());
      }
      ComponentEntity currentActor=(ComponentEntity)readyToScheduleActorList.at(0);
      readyToScheduleActorList.exclude(currentActor);
      _debug("String_Node_Str" + currentActor.getName());
      _simulateInputConsumption(currentActor,waitingTokens);
      newSchedule.insertLast(currentActor);
      Enumeration aOutputPorts=((Actor)currentActor).outputPorts();
      while (aOutputPorts.hasMoreElements()) {
        IOPort aOutputPort=(IOPort)aOutputPorts.nextElement();
        Integer createdTokens=new Integer(_getTokenProductionRate(aOutputPort));
        _simulateTokensCreated(aOutputPort,actorList,readyToScheduleActorList,waitingTokens);
      }
      int firingsRemaining=_getFiringCount(currentActor);
      firingsRemaining-=1;
      _setFiringCount(currentActor,firingsRemaining);
      _debug(currentActor.getName() + "String_Node_Str" + firingsRemaining+ "String_Node_Str");
      if (firingsRemaining < 0)       throw new IllegalStateException("String_Node_Str" + "String_Node_Str" + "String_Node_Str");
 else {
        if (firingsRemaining == 0) {
          unscheduledActorList.removeOneOf(currentActor);
        }
 else {
          int inputCount=_countUnfulfilledInputs((Actor)currentActor,unscheduledActorList,waitingTokens);
          if (inputCount < 1)           readyToScheduleActorList.insertLast(currentActor);
        }
      }
    }
  }
 catch (  NoSuchElementException e) {
    _debug("String_Node_Str");
    _debug(e.getMessage());
    done=true;
  }
catch (  IllegalActionException iae) {
    throw new InternalErrorException("String_Node_Str" + "String_Node_Str" + iae.getMessage());
  }
 finally {
    _debug("String_Node_Str");
  }
  Enumeration eschedule=newSchedule.elements();
  _debug("String_Node_Str");
  while (eschedule.hasMoreElements())   _debug(((ComponentEntity)eschedule.nextElement()).toString());
  return newSchedule;
}