예제 #1
0
파일: Chopstick.java 프로젝트: ptII/ptII
  /**
   * Executes the code in this actor. This actor uses a CDO construct when it is waiting to be used
   * by either of the philosophers next to it. Once one of the philosophers is using it, this actor
   * waits to receive a message that the philosopher is finished eating (using it). It is a good
   * example of using a CDO. This process continues executing until a TerminateProcessException is
   * thrown.
   *
   * @exception IllegalActionException If an error occurs during executing the process.
   * @exception TerminateProcessException If the process termination is requested by the director.
   */
  public void fire() throws IllegalActionException {
    super.fire();
    try {
      boolean guard = true;
      boolean continueCDO = true;
      ConditionalBranch[] branches = new ConditionalBranch[2];
      Token t = new IntToken(0);

      while (continueCDO) {
        // step 1
        branches[0] = new ConditionalSend(guard, leftOut, 0, 0, t);
        branches[1] = new ConditionalSend(guard, rightOut, 0, 1, t);

        // step 2
        int successfulBranch = chooseBranch(branches);

        // step 3
        if (successfulBranch == 0) {
          // Wait for philosopher on left to finish eating.
          leftIn.get(0);
        } else if (successfulBranch == 1) {
          // Wait for philosopher on right to finish eating.
          rightIn.get(0);
        } else if (successfulBranch == -1) {
          // all guards false so exit CDO
          continueCDO = false;
        } else {
          throw new IllegalActionException(
              getName() + ": " + "invalid branch id returned during execution " + "of CDO.");
        }
      }
    } catch (NoTokenException ex) {
      throw new IllegalActionException(getName() + ": cannot " + "get token.");
    }
  }
예제 #2
0
 /**
  * If there are available resources, then perform a conditional branch on any <i>release</i> input
  * or <i>grant</i> output. If the selected branch is a release input, then add the provided token
  * to the end of the resource pool. If it is a grant output, then remove the first element from
  * the resource pool and send it to the output. If there are no available resources, then perform
  * a conditional branch only on the release inputs.
  *
  * @exception IllegalActionException If an error occurs during executing the process.
  * @exception TerminateProcessException If the process termination is requested by the director.
  */
 public void fire() throws IllegalActionException {
   super.fire();
   if (_debugging) {
     _debug("Resources available: " + _pool);
   }
   int numberOfConditionals = release.getWidth();
   if (_pool.size() > 0) {
     numberOfConditionals += grant.getWidth();
   }
   ConditionalBranch[] branches = new ConditionalBranch[numberOfConditionals];
   for (int i = 0; i < release.getWidth(); i++) {
     // The branch has channel i and ID i.
     branches[i] = new ConditionalReceive(release, i, i);
     if (_debugging && _VERBOSE_DEBUGGING) {
       branches[i].addDebugListener(this);
     }
   }
   if (_pool.size() > 0) {
     Token token = (Token) _pool.get(0);
     for (int i = release.getWidth(); i < numberOfConditionals; i++) {
       int channel = i - release.getWidth();
       branches[i] = new ConditionalSend(grant, channel, i, token);
       if (_debugging && _VERBOSE_DEBUGGING) {
         branches[i].addDebugListener(this);
       }
     }
   }
   int successfulBranch = chooseBranch(branches);
   if (_debugging && _VERBOSE_DEBUGGING) {
     for (int i = 0; i < branches.length; i++) {
       branches[i].removeDebugListener(this);
     }
   }
   if (successfulBranch < 0) {
     _branchEnabled = false;
   } else if (successfulBranch < release.getWidth()) {
     // Rendezvous occurred with a release input.
     _branchEnabled = true;
     Token received = branches[successfulBranch].getToken();
     _pool.add(received);
     if (_debugging) {
       _debug("Resource released on channel " + successfulBranch + ": " + received);
     }
   } else {
     // Rendezvous occurred with a grant output.
     _branchEnabled = true;
     if (_debugging) {
       _debug(
           "Resource granted on channel "
               + (successfulBranch - release.getWidth())
               + ": "
               + _pool.get(0));
     }
     _pool.remove(0);
   }
 }
예제 #3
0
 /**
  * Override the base class to reset the resource pool to match the specified initialPool value.
  *
  * @param attribute The attribute that changed.
  * @exception IllegalActionException If the change is not acceptable to this container (not thrown
  *     in this base class).
  */
 public void attributeChanged(Attribute attribute) throws IllegalActionException {
   if (attribute == initialPool) {
     ArrayToken pool = (ArrayToken) initialPool.getToken();
     // Reset the pool.
     _pool.clear();
     // Copy the tokens into the pool.
     for (int i = 0; i < pool.length(); i++) {
       _pool.add(pool.getElement(i));
     }
   } else {
     super.attributeChanged(attribute);
   }
 }
예제 #4
0
 /**
  * Return true unless none of the branches were enabled in the most recent invocation of fire().
  *
  * @return True if another iteration can occur.
  */
 public boolean postfire() {
   super.postfire();
   return _branchEnabled;
 }