Package org.jcsp.lang

# Interface CSProcess

All Known Implementing Classes:
  `ActiveApplet`, `ActiveButton`, `ActiveButtonControl`, `ActiveCanvas`, `ActiveCheckbox`, `ActiveCheckboxMenuItem`, `ActiveChoice`, `ActiveClosingFrame`, `ActiveComponent`, `ActiveContainer`, `ActiveDialog`, `ActiveFileDialog`, `ActiveFrame`, `ActiveLabel`, `ActiveList`, `ActiveMenu`, `ActiveMenuItem`, `ActivePanel`, `ActiveScrollbar`, `ActiveScrollPane`, `ActiveTextArea`, `ActiveTextEnterArea`, `ActiveTextEnterField`, `ActiveTextField`, `ActiveWindow`, `And`, `AndInt`, `BlackHole`, `BlackHoleInt`, `Delta`, `Delta2`, `Delta2Int`, `DeltaInt`, `Demultiplex`, `DemultiplexInt`, `Deparaplex`, `DeparaplexInt`, `DynamicDelta`, `DynamicDeltaInt`, `Fibonacci`, `FibonacciInt`, `FixedDelay`, `FixedDelayInt`, `FramedButton`, `FramedButtonArray`, `FramedButtonGrid`, `FramedScrollbar`, `Generate`, `GenerateInt`, `Identity`, `IdentityInt`, `Integrate`, `IntegrateInt`, `Merge`, `Merge2`, `Merge2Int`, `MergeInt`, `Mult`, `MultInt`, `Multiplex`, `MultiplexInt`, `Nand`, `NandInt`, `Nor`, `NorInt`, `Numbers`, `NumbersInt`, `Or`, `OrInt`, `Pairs`, `PairsInt`, `Parallel`, `Paraplex`, `ParaplexInt`, `Plex`, `Plex2`, `Plex2Int`, `PlexInt`, `Plus`, `PlusInt`, `Prefix`, `PrefixInt`, `Printer`, `PrinterInt`, `PriParallel`, `ProcessManager`, `ProcessRead`, `ProcessReadInt`, `ProcessWrite`, `ProcessWriteInt`, `Regular`, `RegularInt`, `Regulate`, `RegulateInt`, `Sequence`, `Sign`, `SignInt`, `Skip`, `Squares`, `SquaresInt`, `Stop`, `Substitute`, `SubstituteInt`, `Successor`, `SuccessorInt`, `Tail`, `TailInt`, `Times`, `TimesInt`, `Xor`, `XorInt`

public interface CSProcess
This is the JCSP interface for a process - an active component that encapsulates the data structures on which it operates.

## Description

A CSP process is a component that encapsulates data structures and algorithms for manipulating that data. Both its data and algorithms are private. The outside world can neither see that data nor execute those algorithms. Each process is alive, executing its own algorithms on its own data. Processes interact solely via CSP synchronising primitives, such as channels, events or other well-defined modes of access to shared passive objects.

In this JCSP binding of the CSP model into Java, a process is an instance of a class implementing this `CSProcess` interface. Its actions are defined by the `run` method.

Running processes interact solely via CSP channels, events or carefully synchronised access to shared objects -- not by calling each other's methods. These passive objects form the CSP interface to a process. They are not present in the Java interface and must be configured into each process via public constructors and/or mutators when it is not running (i.e. before and in between runs). It is safe to extract information from the process via accessor methods, but only after (or in between) runs.

For other general information, see the JCSP overview.

## Process Oriented Design

A process-oriented design consists of layered networks of processes. A network is simply a parallel composition of processes connected through a set of passive synchronisation objects (wires) and is itself a process. Each process fulfills a contract with its environment that specifies not only what functions it performs, but how it is prepared to synchronise with that environment to obtain information and deliver results. Note that a process does not interact directly with other processes, only with the wires to which it is connected. This is a very familiar form of component interface -- certainly to hardware engineers -- and is one that allows considerable flexibility and reuse.

### Implementation Pattern

The structure of a JCSP process should follow the outline:

     import org.jcsp.lang.*;
     ...  other imports

     class ProcessExample implements CSProcess {

       ...  private/protected shared synchronisation objects (channels etc.)
       ...  private/protected state information

       ...  public constructors
       ...  public configuration/inspection methods (when not running)

       ...  private/protected support methods (part of a run)
       ...  public run method (the process starts here)

     }

The pattern of use for these methods is simple and well-disciplined. The public constructors and configuration methods must install the shared synchronisation objects into their private/protected fields. They may also initialise other private/protected state information. The public configuration/inspection methods (simple `set`s and `get`s) may be invoked only when this process is not running and are the responsibility of a single process only -- usually the process that constructed it. That process is also responsible for invoking the public `run` method that kicks this one into life (usually, via a `Parallel` or `ProcessManager` intermediary). The private support methods are triggered only by the `run` method and express the live behaviour of this process.

A process instance may have several lives but these must, of course, be consecutive. Different instances of the same process class may, also of course, be alive concurrently. Reconfiguration of a process via its configuration/inspection methods may only take place between lives. Dynamic reconfiguration of a live process may take place -- but only with the active cooperation of the process (for example, through channel communication).

### Motivation

Like any object, a process should encapsulate a coherent set of data and algorithms for managing that data. The discipline outlined in the above implementation pattern has the following broad aims:

- maintain the encapsulation of information (which is something that is easilly lost in free-wheeling OO-design as object references are passed around);
- enable a precise (CSP) specification of the way a process interacts with its environment (represented in the above pattern by the shared synchronisation objects);
- express the behaviour of the process from its own point of view (which is something not available to general OO-design whenever a method of one object is invoked from the method of another);
- eliminate the occurrence of race hazards upon the parallel composition of processes;
- enable formal certification of the absence of deadlock, livelock and process starvation in a parallel system (through design-time analysis or the checked adherence to higher-level CSP design rules for which proven safety guarantees are known).

These properties mean that processes make excellent building blocks for complex systems -- their semantics compose cleanly and predictably as they are plugged together.

This is not to say that the semantics of processes connected in parallel are simply the sum of the semantics of each individual process -- just that those semantics should contain no surprises. Value can added just through the nature of the parallel composition itself. For example, connect simple stateless processes into a channel feedback-loop, give them some external wires and we get a component that contains state.

### Discussion

The public methods of an arbitrary object are at the mercy of any other object that has a reference to it. Further, invocations of those methods may be part of any thread of control. Object designers, implementors and users need to have this under well-documented control. This control is not easy to achieve without any rules.

The process design pattern defines some powerful simplifications that bring us that control. Backed up with the theory of CSP, it also addresses and offers solutions to some fundamental issues in concurrency and multi-threading.

In unconstrained OO, threads and objects are orthogonal notions -- sometimes dangerously competitive. Threads have no internal structure and can cross object boundaries in spaghetti-like trails that relate objects together in a way that has little correspondence to the original OO design. A process combines these ideas into a single concept, gives it structure and maintains strong encapsulation by guarding the distribution and use of references with some strict (and checkable) design rules. A process may be wired up in parallel with other processes to form a network -- which is itself a process. So, a process may have sub-processes that have sub-sub-processes ad infinitum. This is the way the world works ...

The simplicity of the process design pattern is that each process can be considered individually as an independant serial program, interacting with external I/O devices (the synchronisation objects -- channels etc.). At the other end of those devices may lie other processes, but that is of no concern to the consideration of this process. All our past skills and intuition about serial programming can safely be applied. The new skills needed to design and use parallel process networks sit alongside those earlier skills and no cross-interference takes place.

## Examples

Numerous examples are scattered throughout the documentation of this library. Good starting ponts are in the `Parallel` and `Alternative` classes. Here is another very simple one:

     import org.jcsp.lang.*;

     // LaunchControl is a process to control the launch of a space rocket.

     // It is configured with a countdown time in seconds -- this must be above
     // a minimum threshold, MIN_COUNTDOWN, else the launch is immediately aborted.

     // There are two control lines, abort and hold, that respectively abort
     // or hold the launch if signalled.  The hold is released by a second
     // signal on the same line.

     // During countdown, the count is reported by outputting on the countdown
     // channel.

     // If not aborted, LaunchControl fires the rocket (by outputting on its fire
     // channel) when the countdown reaches zero.  An ABORTED launch is also
     // reported on this fire channel.

     // After a successful or aborted launch, LaunchControl terminates.
     // The status attribute records whether the launch was FIRED or ABORTED
     // and may then be inspected.

     public class LaunchControl implements CSProcess {

       public static final int MIN_COUNTDOWN = 10;

       public static final int FIRED = 0;
       public static final int HOLDING = 1;
       public static final int COUNTING = 2;
       public static final int ABORTED = 3;
       public static final int UNDEDFINED = 4;

       private final int start;
       private final AltingChannelInputInt abort;
       private final AltingChannelInputInt hold;
       private final ChannelOutputInt countdown;
       private final ChannelOutputInt fire;

       private int status = UNDEDFINED;

       public LaunchControl (final int start,
                             final AltingChannelInputInt abort,
                             final AltingChannelInputInt hold,
                             final ChannelOutputInt countdown,
                             final ChannelOutputInt fire) {
         this.start = start;
         this.abort = abort;
         this.hold = hold;
         this.countdown = countdown;
         this.fire = fire;
       }

       public int getStatus () {                   // inspection method
         return status;                            // (can only be used in between runs)
       }

       public void run () {

         final CSTimer tim = new CSTimer ();        // JCSP timers have
         final long oneSecond = 1000;               // millisecond granularity

         long timeout = tim.read () + oneSecond;    // compute first timeout

         final Alternative alt =
           new Alternative (new Guard[] {abort, hold, tim});
         final int ABORT = 0;
         final int HOLD = 1;
         final int TICK = 2;

         int count = start;
         boolean counting = (start >= MIN_COUNTDOWN); // abort if bad start

         while ((count > 0) invalid input: '&'invalid input: '&' counting) {
           countdown.write (count);                   // public address system
           tim.setAlarm (timeout);                    // set next timeout
           switch (alt.priSelect ()) {
             case ABORT:                              // abort signalled
               abort.read ();                         // clear the signal
               counting = false;
             break;
             case HOLD:                               // hold signalled
               long timeLeft = timeout - tim.read (); // time till next tick
               hold.read ();                          // clear the signal
               fire.write (HOLDING);                  // signal rocket
               hold.read ();                          // wait for the release
               timeout = tim.read () + timeLeft;      // recompute next timeout
               fire.write (COUNTING);                 // signal rocket
             break;
             case TICK:                               // timeout expired
               count--;
               timeout += oneSecond;                  // compute next timeout
             break;
           }
         }

         status = (counting) ? FIRED : ABORTED;       // set status attribute
         fire.write (status);                         // signal rocket (go/nogo)
         if (counting) countdown.write (0);           // complete countdown
       }
     }

Author:
  P.D. Austin, P.H. Welch
See Also:
  - `Parallel`
  - `PriParallel`
  - `Alternative`
  - `ChannelInput`
  - `ChannelOutput`
  - `One2OneChannel`
  - `Any2OneChannel`
  - `One2AnyChannel`
  - `Any2AnyChannel`
  - `ChannelInputInt`
  - `ChannelOutputInt`
  - `One2OneChannelInt`
  - `Any2OneChannelInt`
  - `One2AnyChannelInt`
  - `Any2AnyChannelInt`
  - `ProcessManager`

## Method Summary

Modifier and Type
Method
Description
`void`
`run()`
This defines the actions of the process.

## Method Details

### run

void run()
This defines the actions of the process.