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

Java threads and occam processes



From: Gerald Hilderink <hildernk@xxxxxxxxxxxxxxxx>
To: occam-com@xxxxxxxxx
Subject: Java threads and occam processes

ComsTime Java source code at ftp://ftp.rt.el.utwente.nl/pub/java/comstime.

Peter Welch wrote a nice Java example of ComsTime. My attempt was also to
translate ComsTime from Occam to Java, but with a different approach. 
Without looking at the Occam language in detail I want to implement the
data-flow concept in an object-oriented manner. The use and the behaviour of
channels, the SEQ-construct, the PAR-construct and processes are of
interest. As a result the channel I implemented is different in the
following way: I merged the Occam channel (memory-less channel) and the
buffered channel (memory channel) together into one channel-class, instead
of defining CHAN_OF_INT and BUFFER_OF_INT classes. There are a few reasons
for this approach.

1.	Imagine a channel with a buffer where the buffer size can range between
zero and the available memory; buffersize=n where 0 <= n <= m, m = available
memory (not 1 <= n <= m). 
	The buffer size determines the communication behaviour. When buffersize = 0
then the channel behaviour is fully synchronised. The channel is memory-less
and behaves as an Occam channel. When buffersize = n and 1 <= n <= k (k is
small, k=2) then the channel is quasi-synchronised. If the channel is empty
or full the channel is synchronised. If the channel is not empty or not full
the channel is asynchronous. This is reader or writer process dependent.
When buffersize>>1 (large enough) and the empty and full states are never
reached, the channel behaviour is fully asynchronous. The buffer can also be
of FIFO or LIFO type. The buffer is by default FIFO. The LIFO type can be
used as a stack mechanism. The channel can be configured as a memory-less or
as a memory channel.
	
2.	Declaration of a channel is as follows. Here the Channel declaration is
for integer data types. Channel configurations are given by arguments. 
Examples are:

	Channel ch1 = new Channel();		// memory-less channel (Occam channel)
	Channel ch1 = new Channel(0);		// same as previous
	Channel ch1 = new Channel(2);		// memory channel with two buffer elements
(FIFO)
	Channel ch1 = new Channel(2,FIFO);	// same as previous
	Channel ch1 = new Channel(2,LIFO);	// memory channel with two buffer
elements (LIFO)
					// data is read in reverse order

3.	The behaviour of channels can be adjusted at run-time by statements as:

	ch1.setBufferSize(1);			// reconfigure buffer size to 1 
                                                                            
              // (solve deadlock situation)
                                             

	There are other applications, such as buffer is too small, make it larger.

4.	I am thinking of more features to build in such as debugging and
monitoring channels at run-time.

The prototype class Channel is of type integer. Polymorphism will be added
later. Then I will rename it as CHAN_OF_INT or as ChannelInteger or as
Channel_Int or just Channel(Object) where Object is Integer, Float, Long,
Double, Boolean or a custom object. The latter makes channels untyped. I am
not sure which mechanism I will use; polymorphism or genericity. Perhaps I
use the Occam like notation as Peter did.

Channel types:	                  CHAN_OF_INT
			CHAN_OF_LONG
			CHAN_OF_FLOAT
			CHAN_OF_DOUBLE
			CHAN_OF_OBJECT
			and
			CHAN_OF_PROTOCOL

I use wread/sread and wwrite/swrite instead of in and out or read and write.
The methods wread/sread and wwrite/swrite work on memory-less channels and
on memory channels as well. In addition I can implement the SEQ- and
PAR-constructs. 

Peter's approach:	in and out		for Occam like channels
		read and write	for buffered channels

My approach:	wread and wread		for SEQ construct (Occam and buffered channels)
		sread and swrite		for PAR construct (Occam and buffered channels)
additionally	                  aread and awrite		for polling and override
constructs 

Please, check also my paper on this at our ftp site
ftp://ftp.rt.el.utwente.nl/java/comstime/comstime.ps for the implementation
of the PAR-, PRI-PAR-, ALT- and the PRI-ALT-constructs.

Results:
The results of ComsTime is between the 1.5 and 0.9 ms per iteration on a 120
MHz Pentium under eXceed. 
This morning it took 0.68 ms on a not too busy Sparc 5 station.

After creating threads the Thread.yield() method is used by the channels to
deschedule the waiting thread. This method is native code and it should be
fast. The method calls are the worst problem. Because Java administrates
classes and method in a symbolic manner there is a lot be done when a call
to a method is made. The continuous wwrite/wread/swrite/sread calls are
decreasing the performance. The synchronised (this) modifier locks critical
sections through a monitor. 
This synchronised modifier is very slow in Java. 

	Speeding up the program without changing the standard classes is difficult.
The Java interpreter simply is to slow, this should be sped up first before
we can use it in real-time at all. Perhaps Just-In-Time compilers could
help. I'lll see.



Regards,

Gerald Hilderink
hildernk@xxxxxxxxxxxxxxxx