Pages

Tuesday, March 8, 2016

Mel Abortions

Welcome » NERWous C » Mel
  1. Abort Operation
  2. Abort Value
  3. Abort and Close
  4. Abort Multi-Value


Abort Operation

In the previous example of the Producer / Consumer, we have a OneTimeConsumer that gets out of the resumed waits rather abruptly, by terminating its task with a return statement. For a more refined exit strategy, the following code shows the use of the abort mel operation.
void OneTimeConsumer (<mel> int store) {
     int retries = 5;
     int myprio = 10;
     try {
        Consume(<? timeout priority=myprio>store);
        printf ("I just consumed [%d]", store);
     } catch ( store<TIMEDOUT> ) {
         if ( --retries >= 0 ) {
             myprio++;
             <resume priority=myprio timeout+1>store;
         }
         
         <close>store;     // close to inform the producer of no more consumption
         <abort value=0>store;
     }

     return;     // exit the task
}
When all the retries it can support have exhausted, OneTimeConsumer closes the mel store to inform any late-coming producers not to bother with this channel. It then invokes the mel operation abort with a special value to mark that there is no bona-fide product (here we choose 0). The code flow resumes at the <? timeout priority=myprio>store statement where the mel wait is now broken by abort. The special value of 0 is given to Consume so it can do whatever it needs to do with a non-product value. When Consume returns, the code flow to the printf statement, then out of the try / catch block, and finally to the return statement where the task OneTimeConsumer terminates.


Abort Value

In the above code, we see that the abort operation contains a returned value. This value initializes the value property of the mel store. This value property is normally initialized by the mel wait statement through the retrieval of an item from the mel queue. The abort operation seeds this value locally without going over the network to the remote mel.

If the abort returned value is not specified, the value property of the mel variable retains the value of the last successfully retrieved item from the mel queue. If no retrieval has been done successfully, the value property contains an undefined value. Therefore, although syntactically optional, the abort returned value is logically required so that the code can handle non-produced item deterministically.


Abort and Close
Due to its work being local, the abort operation can be run after the close operation without raising the CLOSED exception like other mel operations.

The close operation, if needed, must be put before the abort operation since abort makes the code flow jump back to the mel wait operation. Any statement after abort within the execution block will be ignored.


Abort Multi-Value
In the example on mel AND waits, we show a Consumer that consumes two mel elements at the same time. Let's modify our OneTimeConsumer to do the same, and see how we can program the abort operation:
void OneTimeConsumer (<mel> int store1, <mel> int store2) {
     int retries = 5;
     int myprio = 10;
     try {
        ConsumeTwo(<? timeout priority=myprio>(store1 && store2));
        printf ("I just consumed [%d] and [%d]", store1, store2);
     } catch ( (store1 && store2)<TIMEDOUT> ) {
         if ( --retries >= 0 ) {
             myprio++;
             <resume priority=myprio timeout+1>(store1 && store2);
         }
         
         <close>store1;    
         <close>store2;
         <abort value=(0, 0)>(store1 && store2);
     }

     return;     // exit the task
}
Since the mel wait is on both mel variables, the abort operation must be applied to both, with two return values for the ConsumeTwo function that requires two arguments.

In the above example, it is a compile-time error to do an abort just on an individual mel (e.g. <abort value=0>store1), while the mel wait is on multiple mel variables.


Previous Next Top

No comments:

Post a Comment