예제 #1
0
 private void handleFirstRX(SinkData channel, Time currentTime)
     throws NoTokenException, IllegalActionException {
   // Method to handle the first stage, receiving the first synchronisation pulse
   IntToken token = (IntToken) input.get(0); // Retrieve the token from the input
   Time timeDelta =
       currentTime.subtract(
           waitTime); // Calculate a delta between the current time and when the channel was
                      // changed, to find the waiting time
   if (timeDelta.getDoubleValue() <= 1.5
       && token.equals(
           1)) { // Token is 1, and we have been waiting for longer than 1.5s. So we will not have
                 // a follow-up token, so can't be used for determining t
     channelQueue
         .remove(); // Send the current channel to the back of the queue so we can do something
                    // useful while it is in its sleep state
     channelQueue.add(currentChannel);
     return;
   }
   if (!channel
       .secondRun) { // If this is the first time we have received packets on the channel we will
                     // need the current time to calculate a t
     channel.t = currentTime;
   }
   channel.state = states.SECONDRX; // Set the channel state to the next stage
   channel.firstValue = token.intValue(); // Store the value we have received
   System.out.println("FIRSTRX on channel " + currentChannel + " currentTime is " + currentTime);
 }
예제 #2
0
 /**
  * If the argument is the meanTime parameter, check that it is positive.
  *
  * @param attribute The attribute that changed.
  * @exception IllegalActionException If the meanTime value is not positive.
  */
 @Override
 public void attributeChanged(Attribute attribute) throws IllegalActionException {
   if (attribute == meanTime) {
     double mean = ((DoubleToken) meanTime.getToken()).doubleValue();
     if (mean <= 0.0) {
       throw new IllegalActionException(
           this, "meanTime is required to be positive.  meanTime given: " + mean);
     }
   } else if (attribute == values) {
     ArrayToken val = (ArrayToken) values.getToken();
     $ASSIGN$_length(val.length());
   } else if (attribute == stopTime) {
     double newStopTimeValue = ((DoubleToken) stopTime.getToken()).doubleValue();
     if (_executing) {
       Time newStopTime = new Time(getDirector(), newStopTimeValue);
       Director director = getDirector();
       if (director != null) {
         Time currentTime = director.getModelTime();
         if (newStopTime.compareTo(currentTime) > 0) {
           director.fireAt(this, newStopTime);
         } else {
           throw new IllegalActionException(
               this, "The stop time " + "is earlier than the current time.");
         }
       }
       $ASSIGN$_stopTime(newStopTime);
     }
   } else {
     super.attributeChanged(attribute);
   }
 }
예제 #3
0
 private void handleFirstTX(SinkData channel, Time currentTime)
     throws NoRoomException, IllegalActionException {
   // Method to handle the third stage, transmitting the first packet to a sink
   IntToken token = new IntToken(currentChannel); // Create a token to send
   output.send(0, token); // Send the token
   if (channel.n
       != null) { // If we have already calculated n in a previous stage (if n is 1) we can skip
                  // straight to the next transmission period
     setNextFireTime(channel, currentTime.getDoubleValue() + (channel.t.getDoubleValue() * 12));
     channel.state = states.SECONDTX;
   } else { // If we do not know n then we need to next fire at the beginning of the next
            // synchronisation phase so we can receive the first pulse and find n
     setNextFireTime(
         channel, currentTime.getDoubleValue() + (channel.t.getDoubleValue() * 11) - 0.02);
     channel.state = states.NCALC;
   }
   System.out.println(
       "FIRSTTX on channel "
           + currentChannel
           + ". t is "
           + channel.t
           + ". nextFireTime is "
           + channel.nextFireTime
           + " currentTime is "
           + currentTime);
 }
예제 #4
0
 /**
  * Request the first firing either at the start time or at a random time, depending on
  * <i>fireAtStart</i>.
  *
  * @exception IllegalActionException If the fireAt() method of the director throws it, or if the
  *     director does not agree to fire the actor at the specified time.
  */
 @Override
 public void initialize() throws IllegalActionException {
   super.initialize();
   Director director = getDirector();
   if (director == null) {
     throw new IllegalActionException(this, "No director!");
   }
   double stopTimeValue = ((DoubleToken) stopTime.getToken()).doubleValue();
   $ASSIGN$_stopTime(new Time(getDirector(), stopTimeValue));
   Time currentTime = director.getModelTime();
   if (!_stopTime.isInfinite() && _stopTime.compareTo(currentTime) > 0) {
     director.fireAt(this, _stopTime);
     $ASSIGN$_executing(true);
   }
   $ASSIGN$_nextOutputIndex(0);
   $ASSIGN$_nextFiringTime(currentTime);
   $ASSIGN$_outputProduced(false);
   if (((BooleanToken) fireAtStart.getToken()).booleanValue()) {
     _fireAt(currentTime);
   } else {
     _generateRandomNumber();
     $ASSIGN$_nextFiringTime(director.getModelTime().add(_current));
     _fireAt(_nextFiringTime);
   }
 }
예제 #5
0
  /**
   * If this firing is triggered by an event at <i>waitee</i>, then output the waiting time for each
   * prior event arrival at <i>waiter</i> since the last arrival of waitee. If there is no event at
   * <i>waitee</i>, then record the time of arrival of the events at <i>waiter</i>, and produce no
   * output.
   *
   * @exception IllegalActionException If get() or send() throws it.
   */
  public void fire() throws IllegalActionException {
    super.fire();
    Time currentTime = ((DEDirector) getDirector()).getModelTime();

    while (waiter.hasToken(0)) {
      waiter.get(0);
      _waiting.addElement(currentTime);
    }

    boolean godot = false;

    while (waitee.hasToken(0)) {
      waitee.get(0);
      godot = true;
    }

    if (godot) {
      for (int i = 0; i < _waiting.size(); i++) {
        Time previousTime = (Time) _waiting.elementAt(i);
        DoubleToken outToken = new DoubleToken(currentTime.subtract(previousTime).getDoubleValue());
        output.send(0, outToken);
      }

      _waiting.removeAllElements();
    }
  }
예제 #6
0
  /**
   * If the <i>stopTime</i> parameter is changed and the model is executing, then if the new value
   * is greater than zero and greater than the current time, then ask the director to fire this
   * actor at that time. If the new value is less than the current time, then request refiring at
   * the current time.
   *
   * @exception IllegalActionException If the superclass throws it.
   */
  public void attributeChanged(Attribute attribute) throws IllegalActionException {
    if (attribute == stopTime) {
      double newStopTimeValue = ((DoubleToken) stopTime.getToken()).doubleValue();

      if (_executing) {
        Time newStopTime = new Time(getDirector(), newStopTimeValue);
        Director director = getDirector();

        if (director != null) {
          Time currentTime = director.getModelTime();

          if (newStopTime.compareTo(currentTime) > 0) {
            director.fireAt(this, newStopTime);
          } else {
            throw new IllegalActionException(
                this, "The stop time " + "is earlier than the current time.");
          }
        }

        _stopTime = newStopTime;
      }
    } else {
      super.attributeChanged(attribute);
    }
  }
예제 #7
0
  /**
   * Return false if the current time is greater than or equal to the <i>stopTime</i> parameter
   * value. Otherwise, return true. Derived classes should call this at the end of their postfire()
   * method and return its returned value.
   *
   * @exception IllegalActionException Not thrown in this base class.
   */
  public boolean postfire() throws IllegalActionException {
    Time currentTime = getDirector().getModelTime();

    if (currentTime.compareTo(_stopTime) >= 0) {
      return false;
    }

    return true;
  }
예제 #8
0
 private void handleNCalc(SinkData channel, Time currentTime)
     throws NoTokenException, IllegalActionException {
   // Method to handle the fourth stage, where we listen to the first synchronisation pulse to find
   // the value of n
   System.out.println(channel.nextFireTime.getDoubleValue() >= currentTime.getDoubleValue() + 0.4);
   if (channel.nextFireTime.getDoubleValue() >= currentTime.getDoubleValue()) {
     input.get(0);
     return;
   } else if (channel
       .secondRun) { // If we are on the second run through, we have already transmitted twice so
                     // we can stop here
     channel.state = states.FINISHED;
     return;
   } else if (currentTime.subtract(channel.nextFireTime).getDoubleValue()
       > 2) { // There is a large delta between when we were supposed to fire and when we fired, so
              // we probably have a collision with another channel
     channel.secondRun = true; // Store that we will need to go around again for this channel
     channel.state = states.FIRSTRX; // Set the stage back to the beginning so we can restart
     System.out.println(
         "NCALC on channel "
             + currentChannel
             + " n is: "
             + channel.n
             + ". t is "
             + channel.t
             + ". nextFireTime is "
             + channel.nextFireTime
             + " currentTime is "
             + currentTime);
     nextChannel(currentChannel, currentTime);
   } else {
     channel.n = ((IntToken) input.get(0)).intValue();
     setNextFireTime(
         channel, currentTime.getDoubleValue() + (channel.t.getDoubleValue() * channel.n));
     channel.state = states.SECONDTX;
     System.out.println(
         "NCALC on channel "
             + currentChannel
             + " n is: "
             + channel.n
             + ". t is "
             + channel.t
             + ". nextFireTime is "
             + channel.nextFireTime
             + " currentTime is "
             + currentTime);
     nextChannel(currentChannel, currentTime);
     removeFromQueue(currentChannel);
   }
 }
예제 #9
0
 /**
  * If the current time matches the expected time for the next output, then return true. Also
  * return true if the trigger input is connected and has events. Otherwise, return false.
  *
  * @exception IllegalActionException If there is no director.
  */
 @Override
 public boolean prefire() throws IllegalActionException {
   if (_debugging) {
     _debug("Called prefire()");
   }
   for (int i = 0; i < trigger.getWidth(); i++) {
     if (trigger.isKnown() && trigger.hasToken(i)) {
       return true;
     }
   }
   Time currentTime = getDirector().getModelTime();
   if (currentTime.compareTo(_nextFiringTime) == 0) {
     return true;
   }
   return false;
 }
예제 #10
0
 private void nextChannel(int currentChannel, Time currentTime) throws IllegalActionException {
   System.out.println("NEXT CHANNEL at" + currentTime);
   removeFromQueue(currentChannel);
   channelQueue.add(currentChannel);
   nextChannel = channelQueue.peek();
   changeChan = true;
   getDirector().fireAt(this, currentTime.add(0.0000001));
 }
예제 #11
0
  public void initialize() throws IllegalActionException {
    super.initialize();

    init_tim = ((DoubleToken) initial_time.getToken()).doubleValue();

    current_time = getDirector().getModelTime();

    firstSend = current_time.add(init_tim);

    getDirector().fireAt(this, firstSend);

    // Get the simulation Stop time
    DEstop_time = getDirector().getModelStopTime();
    stop_time = DEstop_time.getDoubleValue();

    if (_debugging) _debug("GET STOP TIME: ");
  }
예제 #12
0
  /**
   * If the current time matches one of the times that we have previously recorded as the reception
   * time for a transmission, then deliver the token to the receiver.
   *
   * @exception IllegalActionException If the _transmitTo() method of the base class throws it, i.e.
   *     the token attribute of the reception cannot be converted or the token attribute is null and
   *     the receiver attribute of the receptions does not support clear.
   */
  public void fire() throws IllegalActionException {
    super.fire();

    if (_receptions != null) {
      // We may be getting fired because of an impending event.
      Time currentTime = getDirector().getModelTime();
      Double timeDouble = Double.valueOf(currentTime.getDoubleValue());
      Reception reception = (Reception) _receptions.get(timeDouble);

      if (reception != null) {
        // The time matches a pending reception.
        _receptions.remove(timeDouble);

        // Use the superclass, not this class, or we just delay again.
        super._transmitTo(
            reception.token, reception.sender, reception.receiver, reception.properties);
      }
    }
  }
예제 #13
0
 /**
  * Generate an exponential random number and schedule the next firing.
  *
  * @exception IllegalActionException If the director throws it when scheduling the next firing, or
  *     if the director does not agree to fire the actor at the specified time.
  */
 @Override
 public boolean postfire() throws IllegalActionException {
   boolean result = super.postfire();
   Time currentTime = getDirector().getModelTime();
   if (_outputProduced) {
     $ASSIGN$_outputProduced(false);
     $ASSIGN$SPECIAL$_nextOutputIndex(11, _nextOutputIndex);
     if (_nextOutputIndex >= _length) {
       $ASSIGN$_nextOutputIndex(0);
     }
     $ASSIGN$_nextFiringTime(currentTime.add(_current));
     _fireAt(_nextFiringTime);
   } else if (currentTime.compareTo(_nextFiringTime) >= 0) {
     _fireAt(currentTime);
   }
   if (currentTime.compareTo(_stopTime) >= 0) {
     return false;
   }
   return result;
 }
예제 #14
0
  /**
   * Transmit the specified token to the specified receiver with the specified properties. If
   * <i>propagationSpeed</i> is less than Infinity, then this results in a call to fireAt() of the
   * director for each receiver that is in range. The token is not actually transmitted to the
   * receiver until the corresponding invocation of fire() occurs. The time delay is equal to
   * distance/<i>propagationSpeed</i>. See the class comments for the assumptions that make this
   * correct.
   *
   * <p>If the <i>lossProbability</i> is zero, (the default) then the specified receiver will
   * receive the token if it has room. If <i>lossProbability</i> is greater than zero, the token
   * will be lost with the specified probability, independently for each receiver in range. Note
   * that in this base class, a port is in range if it refers to this channel by name and is at the
   * right place in the hierarchy. This base class makes no use of the properties argument. But
   * derived classes may limit the range or otherwise change transmission properties using this
   * argument.
   *
   * @param token The token to transmit, or null to clear the specified receiver.
   * @param sender The sending port.
   * @param receiver The receiver to which to transmit.
   * @param properties The transmit properties (ignored in this base class).
   * @exception IllegalActionException If the token cannot be converted or if the token argument is
   *     null and the destination receiver does not support clear.
   */
  protected void _transmitTo(
      Token token, WirelessIOPort sender, WirelessReceiver receiver, RecordToken properties)
      throws IllegalActionException {
    double speed = ((DoubleToken) propagationSpeed.getToken()).doubleValue();

    if (speed == Double.POSITIVE_INFINITY) {
      super._transmitTo(token, sender, receiver, properties);
    } else {
      Director director = getDirector();

      // FIXME: This isn't right because the receiver
      // may have moved during propagation.  Maybe
      // register a ValueListener to the _location attributes
      // of the receiver actors, and continually recalculate
      // the correct arrival time for the message each time the
      // receiver location changes.  Even so, this will be
      // an approximation, and needs to be fully characterized.
      // Also, the receiver needs to be in range at the
      // conclusion of the propagation, whereas this method is
      // called only if the receiver is in range at the
      // initiation of the transmission.
      WirelessIOPort destination = (WirelessIOPort) receiver.getContainer();
      double distance = _distanceBetween(sender, destination);
      Time time = director.getModelTime().add(distance / speed);

      if (_receptions == null) {
        _receptions = new HashMap();
      }

      Double timeDouble = Double.valueOf(time.getDoubleValue());
      Reception reception = new Reception();
      reception.token = token;
      reception.sender = sender;
      reception.receiver = receiver;
      reception.properties = properties;
      _receptions.put(timeDouble, reception);

      _fireAt(time);
    }
  }
예제 #15
0
 private void handleSecondRX(SinkData channel, Time currentTime)
     throws NoTokenException, IllegalActionException {
   // Method to handle the second stage, receiving the second synchronisation pulse
   if (!channel
       .secondRun) { // If this is the second time we have received packets on the channel we
                     // already have t so no need to calculate it
     channel.t = currentTime.subtract(channel.t);
   }
   int currentValue = ((IntToken) input.get(0)).intValue(); // Retrieve the value from the input
   if (channel.firstValue == 1 && currentValue == 1) { // If the first two values are 1 then n is 1
     channel.n = 1;
     channel.t =
         new Time(getDirector())
             .add(
                 channel.t.getDoubleValue()
                     / 12); // Calculate t given that n is 1, i.e divide the period by 12 as per
                            // the protocol
   }
   setNextFireTime(
       channel,
       currentTime.getDoubleValue()
           + (channel.t.getDoubleValue()
               * currentValue)); // Manually set the next fire time for this channel
   channel.state = states.FIRSTTX; // Set the channel state to the next stage
   System.out.println(
       "SECONDRX on channel "
           + currentChannel
           + ". Current value is "
           + currentValue
           + ". t is "
           + channel.t
           + ". nextFireTime is "
           + channel.nextFireTime
           + " currentTime is "
           + currentTime);
   nextChannel(currentChannel, currentTime);
   removeFromQueue(currentChannel); // We can now move onto listening on the next channel
 }
예제 #16
0
  // NOTE: No clone() method, so don't clone this.
  public void fire() throws IllegalActionException {
    super.fire();
    double increment = 0.0;

    if ((input.getWidth() > 0) && input.hasToken(0)) {
      DoubleToken in = (DoubleToken) input.get(0);
      increment = in.doubleValue();
    }

    output.broadcast(new DoubleToken(value + increment));
    value += 1.0;

    Director director = getDirector();
    Time time = director.getModelTime();
    count++;

    if (count >= 5) {
      director.fireAt(this, time.add(1.0));
      count = 0;
    } else {
      director.fireAt(this, time);
    }
  }
예제 #17
0
 /**
  * Output the current value.
  *
  * @exception IllegalActionException If there is no director.
  */
 @Override
 public void fire() throws IllegalActionException {
   boolean triggerInputPresent = false;
   for (int i = 0; i < trigger.getWidth(); i++) {
     if (trigger.isKnown() && trigger.hasToken(i)) {
       triggerInputPresent = true;
     }
   }
   Director director = getDirector();
   Time currentTime = director.getModelTime();
   boolean timeForOutput = currentTime.compareTo(_nextFiringTime) >= 0;
   if (!timeForOutput && !triggerInputPresent) {
     return;
   }
   if (director instanceof SuperdenseTimeDirector) {
     int currentMicrostep = ((SuperdenseTimeDirector) director).getIndex();
     if (currentMicrostep < 1 && !triggerInputPresent) {
       return;
     }
   }
   super.fire();
   output.send(0, _getValue(_nextOutputIndex));
   $ASSIGN$_outputProduced(true);
 }
예제 #18
0
  /**
   * State machine responsable by receiving the traffic from the data_in port, disassembly the
   * pcredit_outage and send its flits to the output ports (file). If the data_in does not have a
   * token, suspend firing and return.
   *
   * @exception IllegalActionException If there is no director.
   */
  public void fire() throws IllegalActionException {
    super.fire();
    if (_debugging) _debug("fire current_time: " + getDirector().getModelTime());

    // getting current Time
    current_time = getDirector().getModelTime();
    compare_time = current_time.getDoubleValue();

    // if(firstSend.compareTo(compare_time) == 0.0){
    if (compare_time == init_tim) {
      send_msg.send(0, new IntToken("1"));

      if (_debugging) _debug("FIRST sent at: " + compare_time);
      if (compare_time <= stop_time) {
        new_send = ((DoubleToken) interval.getToken()).doubleValue();

        nextSend = current_time.add(new_send);

        getDirector().fireAt(this, nextSend);

        if (_debugging) _debug("after first send at: " + nextSend);
        // Requests to the director to be fire() at the window sample
      }
    } else if (compare_time < init_tim) {
      firstSend = current_time.add(init_tim);

      getDirector().fireAt(this, firstSend);

      if (_debugging) _debug("init_tim at: " + init_tim + " first send at " + firstSend);
    } else if (current_time.getDoubleValue() == nextSend.getDoubleValue()) {
      nextSend = nextSend.add(new_send);
      send_msg.send(0, new IntToken("2"));

      if (_debugging) _debug("msg sent at: " + compare_time);
      if (_debugging) _debug("NEXT SEND AT: " + nextSend);

      getDirector().fireAt(this, nextSend);

    } else if (current_time.getDoubleValue() != nextSend.getDoubleValue()) {
      if (_debugging) _debug("NAO ROLOU " + compare_time);
    }
  } // end public
예제 #19
0
  public void fire() throws IllegalActionException {
    Time currentTime =
        getDirector().getModelTime(); // Get the model time to be used for various calculations

    if (changeChan) { // Check if we need to change the channel in this fire period
      setChannel(nextChannel); // Change to the next required channel
      changeChan = false; // Return to normal operation upon the next fire
      if (input.hasToken(
          0)) { // If this fire was initiated by a token on the input, consume it to avoid loops
        input.get(0);
      }
    } else if (input.hasToken(0)) { // Wireless token has been received f
      SinkData channel =
          channelStore.get(currentChannel); // Retrieve the information for the current channel
      switch (channel.state) { // Determine what stage of the system we are at
        case FIRSTRX: // Stage one, we will be receiving the first synchronisation packet
          handleFirstRX(channel, currentTime);
          break;
        case SECONDRX: // Stage two, we will be receiving the second synchronisation packet
          handleSecondRX(channel, currentTime);
          break;
        case NCALC: // Stage 4, we will be receiving the first synchronisation packet of the
                    // sequence to ascertain the n value
          handleNCalc(channel, currentTime);
          break;
        default: // We are in a state that does not require an input token, so we discard it
          input.get(0);
          break;
      }
    } else { // No token has been received so it is a fire initiated by the source and not a token
             // on the input
      SinkData channel = null; // Initialise a channel to be used later
      int desiredChannelNum =
          currentChannel; // Initialise a variable to store the channel required for this firing
      for (int channelNum :
          channelStore
              .keySet()) { // We need to find the channel that has caused the actor to be fired in
                           // this time period
        channel =
            channelStore.get(channelNum); // Retrieve the information for the channel being checked
        if (channel.nextFireTime != null
            && channel.state
                != states.FINISHED) { // If we have a valid firing time, that has been initialised
          if (!channel.nextFireTime.equals(
              currentTime)) { // We are on an incorrect channel, continue searching
            continue;
          } else { // We have found the correct channel
            desiredChannelNum = channelNum; // Set the desired channel to the channel we have found
            break;
          }
        }
      }
      if (currentChannel == desiredChannelNum) { // If we are on the channel that we desire
        System.out.println(
            channel.nextFireTime.getDoubleValue() <= currentTime.getDoubleValue() + 0.4);
        if (channel.nextFireTime.getDoubleValue()
            <= currentTime.getDoubleValue() + 0.4) { // If we are not too early for the firing time
          switch (channel.state) { // Determine what stage of the system we are at
            case FIRSTTX: // Stage 3, we are in the receive period for the channels sink so we can
                          // transmit a packet
              handleFirstTX(channel, currentTime);
              changeChan = true; // Change back to the channel back to what we had previously
              getDirector().fireAt(this, currentTime.add(0.000001));
              break;
            case SECONDTX: // Stage 5, we are in the receive period for the second time, so we can
                           // transmit a packet
              handleSecondTX(channel, currentTime);
              changeChan = true; // Change back to the channel back to what we had previously
              getDirector().fireAt(this, currentTime.add(0.000001));
              break;
          }
        }
      } else if (desiredChannelNum
          != 0) { // We are not on the desired channel, so we have to change to it
        //		System.out.println(currentChannel + " : " + desiredChannelNum);
        nextChannel =
            currentChannel; // Set the channel we will change back to after the transmit to our
                            // current channel
        setChannel(desiredChannelNum); // Set the channel to the desired channel
        channel.nextFireTime =
            currentTime.add(
                0.0000001); // Set the channels fire time to when we are firing it so we can detect
                            // which channel fired
        getDirector()
            .fireAt(
                this,
                currentTime.add(0.0000001)); // Fire the actor again so we can process the transmit
      }
    }
  }
  /**
   * Schedule a new actor for execution on the next available scheduler 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 deadline of the event.
   * @param executionTime The execution time of the actor.
   * @return Relative time when this Scheduler has to be executed again.
   * @exception IllegalActionException Thrown if actor parameters such as execution time or priority
   *     cannot be read.
   */
  @Override
  public Time schedule(NamedObj actor, Time currentPlatformTime, Time deadline, Time executionTime)
      throws IllegalActionException {
    super.schedule(actor, currentPlatformTime, deadline, executionTime);
    Time minimumRemainingTime = null;
    // Check if is already executing somewhere.
    for (NamedObj schedulerActor : _actors) {
      AtomicExecutionAspect scheduler = (AtomicExecutionAspect) schedulerActor;
      if (scheduler.getRemainingTime(actor) != null
          && scheduler.getRemainingTime(actor).getDoubleValue() > 0.0) {
        // This actor is currently executing on this scheduler.
        Time time = scheduler.schedule(actor, currentPlatformTime, deadline, executionTime);
        notifyExecutionListeners(
            scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.START);
        if (time.getDoubleValue() == 0.0) {
          notifyExecutionListeners(
              scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.STOP);
        }
        _remainingTimeOnCore.put(scheduler, time);
        _lastActorFinished = scheduler.lastActorFinished();
        return time;
      }
    }

    // Its not executing anywhere, find free core.
    for (NamedObj schedulerActor : _actors) {
      AtomicExecutionAspect scheduler = (AtomicExecutionAspect) schedulerActor;
      if (scheduler == this) {
        continue;
      }
      Time remainingTime = _remainingTimeOnCore.get(scheduler);
      if (remainingTime == null || remainingTime.getDoubleValue() == 0.0) {
        Time time = scheduler.schedule(actor, currentPlatformTime, deadline, executionTime);
        notifyExecutionListeners(
            scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.START);
        if (time.getDoubleValue() == 0.0) {
          notifyExecutionListeners(
              scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.STOP);
        }
        _remainingTimeOnCore.put(scheduler, time);
        _lastActorFinished = scheduler.lastActorFinished();
        return time;
      } else {
        if (minimumRemainingTime == null || minimumRemainingTime.compareTo(remainingTime) > 0) {
          minimumRemainingTime = remainingTime;
        }
      }
    }
    return minimumRemainingTime;
  }
예제 #21
0
  /**
   * Get the predicted quantization-event time for a state (QSS-specific).
   *
   * @param stateIdx The state index.
   * @param quantEvtTimeMax The maximum quantization event time.
   */
  protected final Time _predictQuantizationEventTimeWorker(
      final int stateIdx, final Time quantEvtTimeMax) {

    // Note the superclass takes care of updating status variables and
    // storing the returned result.

    // Initialize.
    final ModelPolynomial qStateMdl = _qStateMdls[stateIdx];
    final ModelPolynomial cStateMdl = _cStateMdls[stateIdx];
    final double dq = _dqs[stateIdx];

    // Check internal consistency.
    assert (dq > 0);
    assert (quantEvtTimeMax.getDoubleValue() > 0);
    assert (quantEvtTimeMax.compareTo(qStateMdl.tMdl) > 0);
    assert (quantEvtTimeMax.compareTo(cStateMdl.tMdl) > 0);

    // Find predicted quantization-event time, as change from {tMostRecent}.
    Time tMostRecent;
    double dt;
    if (qStateMdl.tMdl.compareTo(cStateMdl.tMdl) > 0) {
      // Here, most recent event was a quantization-event.
      tMostRecent = qStateMdl.tMdl;
      dt = _predictQuantizationEventDeltaTimeQSS2QFromC(qStateMdl, cStateMdl, dq, _exactInputs);
    } else {
      // Here, most recent event was a rate-event.
      tMostRecent = cStateMdl.tMdl;
      dt = _predictQuantizationEventDeltaTimeQSS2General(qStateMdl, cStateMdl, dq, _exactInputs);
    }

    // Require {dt} > 0.
    if (dt <= 0) {
      // In exact arithmetic, and if the integrator is being stepped properly,
      // this should never happen.  However, if the integrator stepped to a
      // time very close to the previous predicted quantization-event time,
      // or given a small numerator and large denominator in expressions
      // above, can get nonpositive {dt}.
      //   Reset to as small a value as can manage.
      //   Use the `ulp`, the "units in the last place".  From the
      // documentation at {http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html}:
      // "For a given floating-point format, an ulp of a specific real
      // number value is the distance between the two floating-point
      // values bracketing that numerical value."
      // TODO: Construct integrator with "min time step" parameter,
      // and pass it in for use it here.
      dt = java.lang.Math.ulp(tMostRecent.getDoubleValue());
    }

    // Bound result to reasonable limits.
    //   At lower end, need a positive number that, when added to {tMostRecent},
    // produces a distinct time.
    //   At upper end, can't be larger than {quantEvtTimeMax}.
    Time predQuantEvtTime;
    while (true) {
      if (quantEvtTimeMax.subtractToDouble(tMostRecent) <= dt) {
        // Here, tMostRecent + dt >= quantEvtTimeMax.
        //   Note determined this case in a slightly roundabout way, since
        // simply adding {dt} to {tMostRecent} may cause problems if {quantEvtTimeMax}
        // reflects some inherent limitation of class {Time}.
        predQuantEvtTime = quantEvtTimeMax;
        break;
      }
      // Here, tMostRecent + dt < quantEvtTimeMax.
      predQuantEvtTime = tMostRecent.addUnchecked(dt);
      if (predQuantEvtTime.compareTo(tMostRecent) > 0) {
        // Here, added {dt} and got a distinct, greater, time.
        break;
      }
      // Here, {dt} so small that can't resolve difference from {tMostRecent}.
      dt *= 2;
    }

    return (predQuantEvtTime);
  }
예제 #22
0
  /**
   * If a new message is available at the inputs, record it in the list indexed with the time that
   * the message shall be completed, and loop through the list to check whether there is collision.
   * If the current time matches one of the times that we have previously recorded as the completion
   * time for a transmission, then output the received message to the <i>received</i> output port if
   * it is not lost to a collision; otherwise, output it to the <i>collided</i> output port.
   *
   * @exception IllegalActionException If an error occurs reading or writing inputs or outputs.
   */
  public void fire() throws IllegalActionException {
    super.fire();

    Time currentTime = getDirector().getModelTime();

    if (_debugging) {
      _debug("---------------------------------");
      _debug("Current time is: " + currentTime);
    }

    if (message.hasToken(0) && power.hasToken(0) && duration.hasToken(0)) {
      double powerValue = ((DoubleToken) power.get(0)).doubleValue();

      if (_debugging) {
        _debug("Received message with power: " + powerValue);
      }

      if (powerValue < _powerThreshold) {
        // The signal it too weak to be detected, simply drop it.
        message.get(0);
        duration.get(0);

        if (_debugging) {
          _debug("Message power is below threshold. Ignoring.");
        }
      } else {
        // Record the reception.
        Reception reception = new Reception();
        reception.data = message.get(0);
        reception.power = powerValue;
        reception.arrivalTime = currentTime.getDoubleValue();
        reception.collided = false;
        reception.duration = ((DoubleToken) duration.get(0)).doubleValue();

        if (_debugging) {
          _debug("Message is above threshold and has duration: " + reception.duration);
        }

        // Update the total power density.
        _totalPower = _totalPower + reception.power;

        // Put the new reception into the list of prior receptions.
        Time time = currentTime.add(reception.duration);
        reception.expiration = time.getDoubleValue();

        _receptions.add(reception);

        // Schedule this actor to be fired at the end of
        // the duration of the message.
        _fireAt(time);
      }
    }

    // Loop through the prior receptions (and the new one)
    // to mark whether a message is collided according to the new total
    // power density. Also, any prior receptions that are now
    // expiring are sent to one of the two outputs.
    Iterator priorReceptions = _receptions.listIterator();

    while (priorReceptions.hasNext()) {
      Reception priorReception = (Reception) priorReceptions.next();

      if (_debugging) {
        _debug("Checking reception with arrival time: " + priorReception.arrivalTime);
      }

      // If the reception is now expiring, send it to one of the two
      // output ports.
      if (priorReception.expiration == currentTime.getDoubleValue()) {
        if (_debugging) {
          _debug(
              "Current time matches expiration "
                  + "time of a prior message that arrived at: "
                  + priorReception.arrivalTime);
        }

        // The time matches a pending reception.
        priorReceptions.remove();

        // Update the total power.
        _totalPower = _totalPower - priorReception.power;

        // Quantization errors may take this negative. Do not allow.
        if (_totalPower < 0.0) {
          _totalPower = 0.0;
        }

        if (!priorReception.collided) {
          received.send(0, priorReception.data);

          if (_debugging) {
            _debug("Message has been received: " + priorReception.data);
          }
        } else {
          collided.send(0, priorReception.data);

          if (_debugging) {
            _debug("Message has been lost: " + priorReception.data);
          }
        }

        continue;
      }

      // Check the snr to see whether to mark this prior reception
      // collided.
      double powerWithoutThisOne = _totalPower - priorReception.power;

      // Quantization errors may make this negative.
      if (powerWithoutThisOne < 0.0) {
        powerWithoutThisOne = 0.0;
      }

      double snr = priorReception.power / powerWithoutThisOne;

      if (!priorReception.collided && (snr <= _SNRThresholdInDB)) {
        priorReception.collided = true;

        if (_debugging) {
          _debug(
              "Message now has a collision. SNR is: " + snr + ". Total power is: " + _totalPower);
        }
      }
    }
  }