Dear
all,
Our
latest CJT-library (version 0.9.7) has been approved with the 100% Pure Java
Certificate. This library will be available as soon we have received our 100%
Pure Java Logo from Sun Microsystems. This version implement several techniques that will be used for the newest version
0.9.8 (i.e. version 0.9, revision 8).
Here, I
present the newest CJT library version 0.9 (revision 8) Preview 1. This is a
preview version in the hope to get some feedback from this newsgroup before I
put it on our JavaPP site.
CJT 0.9
revision 8 is different from the previous libraries with a different approach.
This version has a Parallel, Sequential, and Alternative construct which are
very close to the OCCAM constructs. Message objects are still copied over
the channel, as in OCCAM, but now reflection techniques are used so that its
contents are copied automatically. The programmer does not need to implementing
a copy(..) method for each message object anymore.
Example
that illustrates the Parallel, Sequential and Alternative
constructs:
Behavior
in CSP
--------------- PROGRAM =
(P1 ; P2 ; ((a -> P3) [] (b -> P4) [] (c -> P5))) || P6
Implementaion in OCCAM
----------------------
PAR
SEQ
P1(..)
P2(..)
ALT
a?message
P3(..)
b?message
P4(..)
c?message
P5(..)
P6
:
Implementation with
CJT
----------------------- Parallel
program = new Parallel(new Process[]
{ new Sequential(new Process[] { new P1(..), new P2(..), new Alternative(new Guard[] { new Guard(a, new P3(a,..)), new Guard(b, new P4(b,..)), new Guard(c, new P5(c,..)) }) }), new P6(..) }); program.start(); // start the construct
a, b, and
c are input channels. P1..P6 are
processes.
Creating
processes is easy:
Public
class P1 implements cjt.Process
{ public P1(channel interface) { } public void run() { // some thing to do } } Every
construct Parallel, Sequential, or Alternative is a process and can be nested.
The Alternative implementation is priority based as in
OCCAM and supports SKIP and TIMEOUT. Guard is not a process but a
real guard that can be enabled/disabled at run-time (unconditional and
conditional).
The priority of a Parallel construct can be set by its
setPriority(..) method. A PriParallel is not included because implementing a
nested PriParallel is hard at the moment.
For
example, an alternative construct with a sequential and
parallel construct:
Alternative alt = new Alternative(new Guard[]
{ new Guard(a, new P1(a,..)), new Guard(b, new Sequential(new Process[] { new P2(b,..), new Parallel(new Process[] { new P3(..), new P4(..) }) }) }); alt.start(); // start the construct
-----------
I wrote a
small program according to the farming model example as described in "How
to Design Deadlock-Free Networks Using CSP and Verification Tools – A
Tutorial Introduction" by Jeremy Martin and S. Jassim.
The
example illustrates the use of the Parallel, Sequential and Alternative
constructs. This implementation uses processes as much as possible. It's not the most efficient
implementation, but this example shows that processes can used in a
compositional (if this is the right word?) way as in CSP.
A farmer
employs n foremen each of whom is responsible for m workers. When a worker
process becomes idle it reports the result of any work done to its foreman,
using channel a.i.j, where j denotes worker and i denotes foreman. The foreman
reports this on channel c.i to the farmer who, in turn, replies with a new task
using channel d.i. The foreman then assigns the new task to the work with
channel b.i.j.
The
worker sleeps for some random time as if it is doing
some work. The output of the program is the numbers of the workers that are served
by the farmer (see Print process in Farmer.java). Here, n = 5 and m =
5.
Download the CJT-library at http://www.rt.el.utwente.nl/javapp/cjt/cjt098.zip
and set the CLASSPATH to cjt098.zip.
The code can be downloaded from http://www.rt.el.utwente.nl/javapp/cjt/farmingmodel.zip.
Start the
program by typing,
java FarmingModel
Stop the output with Ctrl-C. That's all.
Cheers,
Gerald.
--------------------------- Behavior
in CSP
---------------
FARMER =
[]i=0..n-1 c.i -> d.i -> FARMER
FOREMAN(i) = []j=0..m-1 a.i.j -> c.i -> d.i -> b.i.j ->
FOREMAN(i)
WORKER =
a.i.j -> b.i.j -> WORKER
FARMINGMODEL =
WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER
Implementation with CJT
-----------------------
FARMER =
(GUARDPROCESS(c.0,d.0)[]..[]GUARDPROCESS(c.(n-1),d.(n-1)))*
GUARDPROCESS(i) =
READER(c.i,object);PRINT(object);WRITER(d.i,object)
FOREMAN(i) =
(GUARDPROCESS(a.i.0,b.i.0,c.i,d.i)[]..[]GUARDPROCESS(a.i.(m-1),b.i.(m-1),c.i,d.i))*
GUARDPROCESS(i,j) = READER(a.i.j,object);WRITER(c.i,object);
READER(d.i,object);WRITER(b.i.j,object)
WORKER(i,j) =
(SLEEPER(delay);READER(a.i.j,object);WRITER(b.i.j,object))*
FARMINGMODEL =
WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER
--
Farmer.java -------------------------
/*
* Example using CJT version 0.9, revision 8. * * By Gerald Hilderink */ import cjt.*;
import cjt.Process; import cjt.messages.Integer; // Behavior in CSP:
// // FARMER = []i=0..n-1 c.i -> d.i -> FARMER // // Implementation with CJT: // // FARMER = (GUARDPROCESS(c.0,d.0)[]..[]GUARDPROCESS(c.(n-1),d.(n-1)))* // GUARDPROCESS(i) = READER(c.i,object);PRINT(object);WRITER(d.i,object) // public class Farmer implements
Process
{ private Alternative alt; public Farmer(ChannelInput c[], ChannelOutput d[]) { Guard guards[] = new Guard[c.length]; for(int i=0; i<c.length; i++) guards[i] = new Guard(c[i], new GuardProcess(c[i], d[i])); alt = new
Alternative(guards);
} public void run() { while(true) { alt.start(); } } class GuardProcess implements Process { private Sequential seq; public GuardProcess(ChannelInput c, ChannelOutput d) { Integer object = new Integer(); seq = new Sequential(new Process[] { new Reader(c, object), new Print(object), new Writer(d, object) }); } public void run() { seq.start(); } } class Print implements Process { private Object object; public Print(Object object) { this.object = object; } public void run() { System.out.println("Farmer is serving worker: "+object); } } } --
Foreman.java ------------------------
/*
* Example using CJT version 0.9, revision 8. * * By Gerald Hilderink */ import cjt.*;
import cjt.Process; import cjt.messages.Integer; // Behavior in CSP:
// // FOREMAN(i) = []j=0..m-1 a.i.j -> c.i -> d.i -> b.i.j -> FOREMAN(i) // // Implementation with CJT: // // FOREMAN(i) = (GUARDPROCESS(a.i.0,b.i.0,c.i,d.i)[]..[]GUARDPROCESS(a.i.(m-1),b.i.(m-1),c.i,d.i))* // GUARDPROCESS(i,j) = READER(a.i.j,object);WRITER(c.i,object);READER(d.i,object);WRITER(b.i.j,object) // public class Foreman implements
Process
{ private Alternative alt; public Foreman(ChannelInput a[], ChannelOutput b[], ChannelOutput c, ChannelInput d) { Guard guards[] = new Guard[a.length]; for(int i=0; i<a.length; i++) guards[i] = new Guard(a[i], new GuardProcess(a[i], b[i], c, d)); alt = new Alternative(guards); } public void run() { while(true) { alt.start(); } } class GuardProcess implements Process { private Sequential seq; public GuardProcess(ChannelInput a, ChannelOutput b, ChannelOutput c, ChannelInput d) { Integer object = new Integer(); seq = new Sequential(new Process[] { new Reader(a, object), new Writer(c, object), new Reader(d, object), new Writer(b, object) }); } public void run() { seq.start(); } } } --
Worker.java -------------------------
/*
* Example using CJT version 0.9, revision 8. * * By Gerald Hilderink */ import cjt.*;
import cjt.Process; import cjt.messages.Integer; import java.math.*; // Behavior in CSP:
// // WORKER = a.i.j -> b.i.j -> WORKER // // Implementation with CJT: // // WORKER(i,j) = (SLEEPER(delay);READER(a.i.j,object);WRITER(b.i.j,object))* // public class Worker implements
Process
{ private Sequential seq; private Integer object; public Worker(ChannelOutput a, ChannelInput b, int id) { object = new Integer(id); seq = new Sequential(new Process[] { new Sleeper((long)(Math.random()*2000)), new Writer(a, object), new Reader(b, object) }); } public void run() { while(true) { seq.start(); } } class Sleeper implements Process { private long msec; public Sleeper(long msec) { this.msec = msec; } public void run() { try { Thread.sleep(msec); } catch (InterruptedException e) { } } } } --
FarmingModel.java – main program
----
/*
* Example using CJT version 0.9, revision 8. * * By Gerald Hilderink */ import
cjt.*;
import cjt.Process; // Behavior in
CSP:
// // FARMINGMODEL = WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER // // Implementation with CJT: // // FARMINGMODEL = WORKER(0,0)||..||WORKER(n-1,m-1)||FOREMAN(0)||..||FOREMAN(n-1)||FARMER // public class
FarmingModel
{ public static void main(String[] args) { int N = 5; int M = 5; Channel a[][] = new Channel[N][M]; Channel b[][] = new Channel[N][M]; Channel c[] = new Channel[N]; Channel d[] = new Channel[M]; Process process[] = new Process[1+N+M*N]; for(int n=0; n<N; n++) { c[n] = new Channel(); d[n] = new Channel(); for(int m=0; m<M; m++) { a[n][m] = new Channel(); b[n][m] = new Channel(); process[N+m+n*M] = new Worker(a[n][m], b[n][m], m+n*M); } process[n] = new Foreman(a[n], b[n], c[n], d[n]); } process[N+M*N] = new Farmer(c, d); Parallel par = new Parallel(process);
par.start();
} } ----------------------------------------------------------
Gerald H. Hilderink University of Twente, Dept. Electrical Engineering Control Laboratory P.O.Box 217, 7500 AE Enschede, Netherlands phone: +31 53 489 2788, fax: +31 53 489 2223 mailto: g.h.hilderink@xxxxxxxxxxxxx personal Web site: http://www.rt.el.utwente.nl/hdk research Web site: http://www.rt.el.utwente.nl/javapp ---------------------------------------------------------- |