//{{{}}} Dear All, Reminder: if you look at: http://www.hensa.ac.uk/parallel/groups/wotug/java/discussion/ and click on "ALTing", you will find the JavaPP Alternative class and an explanation of how to use it to get ALTing across an array of JavaPP Channels. That class only allowed ALTing with respect to Channel reads. I've now added timeout and SKIP guards to these ALTs. The revised Alternative class will be put up on the above web page shortly, together with an example showing its use (loosely based on the `wot, no chickens?' example). This note documents occam and JavaPP equivalents for ALTing, including the timeout and SKIP guards. //{{{ (PRI) ALT on a channel array (with optional pre-conditions) An occam prioritised ALT against an array of input guards is expressed: PRI ALT i = 0 FOR SIZE c c[i] ? x ... some process (involving i) A Java thread will first need to declare: Alternative alt = new Alternative (); Then, the same prioritised ALT can be expressed: { int i = alt.select (c); x = c[i].read (); ... some process (involving i) } Notice that it is our responsibilty to read from the channel selected -- if we don't, bad things will happen. In occam, this responsibility is taken care for us by the compiler. Often, the channel array will be small (and, if the channels are carrying Java `Objects', each element can be communicating a separate protocol). In such cases, a `switch' statement may be more convenient: switch (alt.select (c)) { case 0: { x = c[0].read (); ... some process (involving 0) break; } case 1: { x = c[1].read (); ... some process (involving 1) break; } case 2: { x = c[2].read (); ... some process (involving 2) break; } } ALTing with pre-conditions is expressed in occam by: PRI ALT i = 0 FOR SIZE c guard[i] & c[i] ? x ... some process (involving i) where `guard[i]' is an array of BOOLEANs (the same size as the channel array). In fact, the `guard[i]' could be any boolean expression in occam -- but for Java, we need to get them into an array. The above pre-conditioned ALT is: { int i = alt.select (c, guard); x = c[i].read (); ... some process (involving i) } //}}} //{{{ (PRI) ALT on a channel array and a timeout (with optional pre-conditions) In occam, we may ALT against a (relative) timeout as follows: INT t: SEQ tim ? t PRI ALT ALT i = 0 FOR SIZE c c[i] ? x ... some process (involving i) tim ? AFTER t PLUS (delay*msecs) ... response to the timeout where `tim' is an occam TIMER and `msecs' is a VAL INT of 1000 (or whatever number of TIMER ticks gives one millisecond). In JavaPP, this becomes: { int i = alt.select (c, delay); // delay is a Java `long' type if (i < c.length) { x = c[i].read (); ... some process (involving i) } else { ... response to the timeout } } Note: the Java `wait' methods (used in the implementation) provide relative timeouts in units of milliseconds. There is also a version of `wait' that provides timeouts in units of milliseconds plus nanoseconds (presumably the milliseconds component would normally be zero). Anyway, we provide versions of `select' that allow similar timeouts to be set. Note: if `delay' is zero or negative, the timeout is deemed to have occured, but it is selected at lower priority than the channels (i.e. only if none of the channels were ready). The occam ALT against an absolute timeout value: PRI ALT ALT i = 0 FOR SIZE c c[i] ? x ... some process (involving i) tim ? AFTER timeout ... response to the timeout requires computing the the relative delay period for JavaPP: { int i = alt.select (c, timeout - System.currentTimeMillis()); if (i < c.length) { x = c[i].read (); ... some process (involving i) } else { ... response to the timeout } } where the absolute `timeout' in the Java is expressed in milliseconds (and calculated from an earlier reading the the system clock) and, again, noting that `timeout' must have type `long'. CAVEAT: no allowance is made in the above for wrap around of the system clock! However, on our UNIX systems, time zero was in the early 1970s and these times are in milliseconds held in Java `long's (64-bit integers). I haven't done the calculation, but look out for a real mother of a Year-2000 type disaster some time around AD 1000000000 ... Finally, we have provided pre-conditions for `select'-with-timeout in the case that both the channels and the timeout have pre-conditions. In occam: PRI ALT ALT i = 0 FOR SIZE c guard[i] & c[i] ? x ... some process (involving i) timeout.condition & tim ? AFTER timeout ... response to the timeout In JavaPP, this becomes: { int i = alt.select (c, guard, timeout - System.currentTimeMillis(), timeout_condition); if (i < c.length) { x = c[i].read (); ... some process (involving i) } else { ... response to the timeout } } //}}} //{{{ (PRI) ALT on a channel array and SKIP (with optional pre-conditions) In occam, we may poll an array of channels by: PRI ALT ALT i = 0 FOR SIZE c c[i] ? x ... some process (involving i) skip.condition & SKIP ... response to no channels being ready where `skip.condition' can be any boolean expression. If this is true, we get a poll on the channels -- i.e. we take the last branch if-and-only-if no channels are ready. If this is false, it's the same as just PRI ALTing on the channels. In JavaPP, this becomes: { int i = alt.select (c, skip_condition); if (i < c.length) { x = c[i].read (); ... some process (involving i) } else { ... response to no channels being ready } } Notice that, as in occam, the SKIP guard has to have a pre-condition -- it's the pre-condition that implies the presence of the SKIP guard!. Finally, we can put pre-conditions on the channels as well as the SKIP guard. In occam: PRI ALT ALT i = 0 FOR SIZE c guard[i] & c[i] ? x ... some process (involving i) skip.condition & SKIP ... response to no channels being ready In JavaPP, this becomes: { int i = alt.select (c, guard, skip_condition); if (i < c.length) { x = c[i].read (); ... some process (involving i) } else { ... response to no channels being ready } } //}}} Although these ALTs do not provide the full flexibility of occam (e.g. many timer guards, many SKIP guards, mixed timer and SKIP guards), I've only ever used them in the ways described above. It's possible someone may want the timer guard to have higher priority than the Channels ... the class could easilly be extended to support this ... please let me know. Peter Welch (17th. June, 1997).