[kepler-dev] [Ptolemy] AbstractReceiver.java

Daniel Crawl crawl at sdsc.edu
Thu May 7 11:05:56 PDT 2009


Hi Christopher,

I made this update to prevent unnecessary artificial deadlocks
in PN under certain circumstances. I can add a test case that
demonstrates the problem.

If the convert is performed, is the update ok? Note that no
tests failed in ptolemy/actor/test/ due to this change...
Since calling convert is essential, I can also add a test case
for this.

There were effectively two nested loops before, so I do not see
how this change could degrade performance. If it is measurably
different, it is improved since the outer loop no longer calls
a method.

Thanks,

  --dan



Christopher Brooks wrote:
> Yep, I went ahead and reverted the change.
>
> _Christopher
>
> Edward A. Lee wrote:
>>
>> The call to convert is essential.
>>
>> Without it, we'll get some very esoteric and difficult to track
>> type system bugs.  A likely manifestation is that actors will
>> start throwing ClassCastException because they have declared
>> an input to be double, so they cast incoming tokens to DoubleToken.
>> Without the call to convert(), they may get, say, an IntToken.
>> This will be a very unfriendly error...
>>
>> Edward
>>
>>
>> Christopher Brooks wrote:
>>> Hi Daniel,
>>> I'm concerned that this is a performance hit because we
>>> have two nested loops.  Can you tell me more about why this
>>> change is necessary?  Do you have a test case that illustrates
>>> the bug?  Without a test case, it is not likely that the fix will
>>> persist, though the comment should help.
>>>
>>> The entire method is:
>>>  /** Put a sequence of tokens to all receivers in the specified array.
>>>      *  Implementers will assume that all such receivers
>>>      *  are of the same class.
>>>      *  @param tokens The sequence of token to put.
>>>      *  @param numberOfTokens The number of tokens to put (the array 
>>> might
>>>      *   be longer).
>>>      *  @param receivers The receivers.
>>>      *  @exception NoRoomException If there is no room for the token.
>>>      *  @exception IllegalActionException If the token is not 
>>> acceptable
>>>      *   to one of the ports (e.g., wrong type), or if the tokens array
>>>      *   does not have at least the specified number of tokens.
>>>      */
>>>     public void putArrayToAll(Token[] tokens, int numberOfTokens,
>>>             Receiver[] receivers) throws NoRoomException,
>>>             IllegalActionException {
>>>         if (numberOfTokens > tokens.length) {
>>>             IOPort container = getContainer();
>>>             throw new IllegalActionException(container,
>>>                     "Not enough tokens supplied.");
>>>         }
>>>
>>>         // Put a single token at a time for each receiver instead of
>>>         // putting the entire array. In the latter case, we may block
>>>         // on a receiver while other receiver(s) starve.
>>>         for(int i = 0; i < numberOfTokens; i++) {
>>>             for (int j = 0; j < receivers.length; j++ ) {
>>>                 receivers[j].put(tokens[i]);
>>>             }
>>>     }
>>>     }
>>>
>>>
>>> I do see how this could be a problem with blocking though.
>>>
>>> Your change is to call put() instead of putArray().
>>> AbstractReceiver.putArray() looks like:
>>>
>>>     public void putArray(Token[] tokenArray, int numberOfTokens)
>>>             throws NoRoomException, IllegalActionException {
>>>         IOPort container = getContainer();
>>>
>>>         // If there is no container, then perform no conversion.
>>>         if (container == null) {
>>>             for (int i = 0; i < numberOfTokens; i++) {
>>>                 put(tokenArray[i]);
>>>             }
>>>         } else {
>>>             for (int i = 0; i < numberOfTokens; i++) {
>>>                 put(container.convert(tokenArray[i]));
>>>             }
>>>         }
>>>     }
>>>
>>> It looks like your change is ok when the container is null, but
>>> in the AbstractReceiver base class it does not handle the call
>>> to convert()?  I'm not sure if this is important or not.
>>>
>>> I'm fairly certain that putArrayToAll() will be called when we call
>>> IOPort.broadcast.
>>>
>>> What do you think?
>>>
>>> _Christopher
>>>
>>> Daniel Crawl wrote:
>>>> Author: crawl
>>>> Date: 2009-05-06 14:45:46 -0700 (Wed, 06 May 2009)
>>>> New Revision: 53516
>>>>
>>>> Modified:
>>>>    trunk/ptolemy/actor/AbstractReceiver.java
>>>> Log:
>>>> Put a single token at a time for each receiver in putArrayToAll().
>>>>
>>>>
>>>> Modified: trunk/ptolemy/actor/AbstractReceiver.java
>>>> ===================================================================
>>>> --- trunk/ptolemy/actor/AbstractReceiver.java    2009-05-06 
>>>> 21:13:26 UTC (rev 53515)
>>>> +++ trunk/ptolemy/actor/AbstractReceiver.java    2009-05-06 
>>>> 21:45:46 UTC (rev 53516)
>>>> @@ -300,8 +300,13 @@
>>>>                      "Not enough tokens supplied.");
>>>>          }
>>>>  
>>>> -        for (int j = 0; j < receivers.length; j++) {
>>>> -            receivers[j].putArray(tokens, numberOfTokens);
>>>> +        // Put a single token at a time for each receiver instead of
>>>> +        // putting the entire array. In the latter case, we may block
>>>> +        // on a receiver while other receiver(s) starve.
>>>> +        for(int i = 0; i < numberOfTokens; i++) {
>>>> +            for (int j = 0; j < receivers.length; j++ ) {
>>>> +                receivers[j].put(tokens[i]);
>>>> +            }
>>>>          }
>>>>      }
>>>>  
>>>>
>>>> _______________________________________________
>>>> Ptexternal-cvs mailing list
>>>> Ptexternal-cvs at chess.eecs.berkeley.edu
>>>> http://chess.eecs.berkeley.edu/ptexternal/listinfo/ptexternal-cvs
>>>
>



More information about the Kepler-dev mailing list