Program: 72849
Project: 72849
Buggy source:
/** 
 * Schedule a new actor for execution and return the next time this scheduler has to perform a reschedule.
 * @param actor The actor to be scheduled.
 * @param currentPlatformTime The current platform time.
 * @param deadline The event deadline - not used here.
 * @param executionTime The execution time of the actor.
 * @return Relative time when this Scheduler has to be executedagain.
 * @exception IllegalActionException Thrown if actor parameters suchas execution time or priority cannot be read.
 */
@Override public Time schedule(Actor actor,Time currentPlatformTime,Time deadline,Time executionTime) throws IllegalActionException {
  super.schedule(actor,currentPlatformTime,deadline,executionTime);
  _lastActorFinished=false;
  Time remainingTime=null;
  if (_currentlyExecuting.size() == 0) {
    scheduleNewActor(actor,currentPlatformTime,executionTime);
    remainingTime=executionTime;
  }
 else {
    Actor executing=_currentlyExecuting.peek();
    Time lasttime=_lastTimeScheduled.get(executing);
    Time timePassed=currentPlatformTime.subtract(lasttime);
    remainingTime=_remainingTimes.get(executing).subtract(timePassed);
    if (remainingTime.getDoubleValue() < 0) {
      throw new IllegalActionException(this,"String_Node_Str");
    }
    _remainingTimes.put(executing,remainingTime);
    if (!_currentlyExecuting.contains(actor) && executing != actor) {
      if (_preemptive) {
        double executingPriority=_getPriority(executing);
        double newActorPriority=_getPriority(actor);
        if (newActorPriority < executingPriority) {
          if (remainingTime.getDoubleValue() == 0.0) {
            notifyScheduleListeners((NamedObj)_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
          }
 else {
            notifyScheduleListeners((NamedObj)executing,currentPlatformTime.getDoubleValue(),ExecutionEventType.PREEMPTED);
          }
          remainingTime=executionTime;
          scheduleNewActor(actor,currentPlatformTime,executionTime);
        }
 else {
          _add(actor,executionTime);
        }
      }
 else {
        Object[] actors=_currentlyExecuting.toArray();
        _currentlyExecuting.clear();
        for (int j=0; j < actors.length; j++) {
          _currentlyExecuting.push((Actor)actors[j]);
        }
        _currentlyExecuting.push(actor);
        _remainingTimes.put(actor,executionTime);
      }
    }
    for (    Actor preemptedActor : _currentlyExecuting) {
      _lastTimeScheduled.put(preemptedActor,currentPlatformTime);
    }
  }
  if (remainingTime.getDoubleValue() == 0.0 && _currentlyExecuting.peek() == actor) {
    notifyScheduleListeners((NamedObj)_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
    _remainingTimes.put(_currentlyExecuting.peek(),null);
    _currentlyExecuting.pop();
    if (_currentlyExecuting.size() > 0) {
      remainingTime=_remainingTimes.get(_currentlyExecuting.peek());
      if (remainingTime.getDoubleValue() > 0.0) {
        notifyScheduleListeners((NamedObj)_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.START);
      }
    }
    _lastActorFinished=true;
    _lastActorThatFinished=actor;
  }
  return remainingTime;
}

Fixed version (ground truth):
/** 
 * Schedule a new actor for execution and return the next time this scheduler has to perform a reschedule.
 * @param actor The actor to be scheduled.
 * @param currentPlatformTime The current platform time.
 * @param deadline The event deadline - not used here.
 * @param executionTime The execution time of the actor.
 * @return Relative time when this Scheduler has to be executedagain.
 * @exception IllegalActionException Thrown if actor parameters suchas execution time or priority cannot be read.
 */
@Override public Time schedule(Actor actor,Time currentPlatformTime,Time deadline,Time executionTime) throws IllegalActionException {
  super.schedule(actor,currentPlatformTime,deadline,executionTime);
  _lastActorFinished=false;
  Time remainingTime=null;
  if (_currentlyExecuting.size() == 0) {
    scheduleNewActor(actor,currentPlatformTime,executionTime);
    remainingTime=executionTime;
  }
 else {
    Actor executing=_currentlyExecuting.peek();
    Time lasttime=_lastTimeScheduled.get(executing);
    Time timePassed=currentPlatformTime.subtract(lasttime);
    remainingTime=_remainingTimes.get(executing).subtract(timePassed);
    _remainingTimes.put(executing,remainingTime);
    if (!_currentlyExecuting.contains(actor) && executing != actor) {
      if (_preemptive) {
        double executingPriority=_getPriority(executing);
        double newActorPriority=_getPriority(actor);
        if (newActorPriority < executingPriority) {
          if (remainingTime.getDoubleValue() == 0.0) {
            notifyScheduleListeners((NamedObj)_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
          }
 else {
            notifyScheduleListeners((NamedObj)executing,currentPlatformTime.getDoubleValue(),ExecutionEventType.PREEMPTED);
          }
          remainingTime=executionTime;
          scheduleNewActor(actor,currentPlatformTime,executionTime);
        }
 else {
          _add(actor,executionTime);
        }
      }
 else {
        Object[] actors=_currentlyExecuting.toArray();
        _currentlyExecuting.clear();
        for (int j=0; j < actors.length; j++) {
          _currentlyExecuting.push((Actor)actors[j]);
        }
        _currentlyExecuting.push(actor);
        _remainingTimes.put(actor,executionTime);
      }
    }
    for (    Actor preemptedActor : _currentlyExecuting) {
      _lastTimeScheduled.put(preemptedActor,currentPlatformTime);
    }
  }
  if (remainingTime.getDoubleValue() == 0.0 && _currentlyExecuting.peek() == actor) {
    notifyScheduleListeners((NamedObj)_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
    _remainingTimes.put(_currentlyExecuting.peek(),null);
    _currentlyExecuting.pop();
    if (_currentlyExecuting.size() > 0) {
      remainingTime=_remainingTimes.get(_currentlyExecuting.peek());
      if (remainingTime.getDoubleValue() > 0.0) {
        notifyScheduleListeners((NamedObj)_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.START);
      }
    }
    _lastActorFinished=true;
    _lastActorThatFinished=actor;
  }
  return remainingTime;
}