/** * 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."); } }
/** * 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); } }
/** * 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); } }
/** * 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; }