andy@snowwhite.UUCP.UUCP (06/30/88)
Links, both hard and soft, are simply elegant. Some basics:
o soft links (ie: an address in memory) are at the programmers
interface no different than hard links. Both are addressed with
a "channel" address, therefore letting *any* word-aligned address
be a channel.
o hard links are in the simplest sense DMA engines. They have a
buffer pointer and a byte count. They send/receive a serial
bit-stream.
o I often mix "channel" and "link", and purest will argue that
they are, in fact, not the same.
At the assembler level (in pseudo-assembler), sending message through a channel:
ldl buffer-pointer
ldl channel-address
ldl number-of-bytes
out
and receiving a message:
ldl buffer-pointer
ldl channel-address
ldl number-of-bytes
in
And in either case the process is blocked until the message is transferred.
Gritty details:
Hard links:
Bytes of the message are DMA'd to/from the CPU, one at a time.
Internally, there is a 2-bit header, 8 data bits, and 1 stop bit.
On T800's, a 2 bit acknowledge message is sent back as soon as
the 2 bit header has arrived. On T414's and I believe T212's,
the entire byte must be assembled at the far end before the
ACK is sent. This happens for every byte of the message, one at
a time.
The Key: the ACK is only sent if and only if some
process on that Transputer is doing an "in" on that hard link.
This is the trick that provides for fully synchronous messages.
When the transfer is completed (ie: the byte count has reached 0),
the "in" process is placed on a queue to run. The same happens with
the "out" process as well.
Nifty things: while INMOS doesn't recommend it, there is absolutely
nothing stopping one from sending a message that is, say, 20000 bytes
long, and receiving it one byte at a time. The reverse also is true.
Soft links:
It depends on who gets to the channel address first. Ordinarily,
an intialized, "empty" link contains the value MinInt (0x80000000
on 32-bit transputers). For our discussion we will assume that
the process doing an "in" arrives at the channel first:
Upon executing the "in" instruction, the contents of the channel
are checked for the value MinInt. If it isn't, then it is assumed
to be a workspace pointer of a process performing an "out."
If it is MinInt, the process' workspace pointer is placed in the
channel, the values pertinent to the transfer (ie: buffer pointer
and byte count) are placed at memory[workspace-X] where X is
(I think) -2 and -3. The processor then starts executing the first
process on the queue, essentially blocking the "in" process.
For our discussion, we now assume that at some future time a process
performs an "out" on a channel containing the workspace pointer of
a process performing an "in." Because the contents of the channel
is not MinInt, we have a rendevous. When this happens, the processor
examines the contents of memory[memory[channel]-3] to find the
buffer pointer, and performs a block-move of bytes from one buffer
pointer to the other. The "out" process then continues execution,
and the formerly blocked "in" process is placed on the run queue.
Implications:
o it is possible, although unwise, to have an "in-in" or "out-out"
pair, as opposed to the normal "in-out" pair. The results are
determined by which process arrived at the channel last.
o it is not advised to create a situation in which the two buffer
pointers overlap. As with the "move" instruction, undetermined
results may occur.
o you can't do a lot of this nifty stuff in Occam.
"ALT's are fun, too."
--
Andy Pfiffer Topologix, Inc. (303) 421-7700
Trillium Diving Team 4860 Ward Road / Denver, CO 80033
"...that's the way a Transputer works, right?"