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?"