[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

JavaPP -- ALTing with timeout and SKIP guards



//{{{}}}

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).