Next: , Previous: , Up: Multithreading and Backtracking   [Index]


10.2 Multithreading using WHILE

INTERCAL-72 C-INTERCAL CLC-INTERCAL J-INTERCAL
no version 0.27+ version 0.05+ no

The WHILE command (which is not strictly speaking a command, but more a sort of metacommand that joins commands) is a second method of achieving multithreading. (In CLC-INTERCAL, there are at least two other meanings for WHILE, but only the one implemented in C-INTERCAL is discussed here.) The syntax is somewhat unusual, and consists of two commands separated by the WHILE keyword, but sharing the statement identifier, execution chance, and any ONCE/AGAIN keyword that may be present. For instance:

(1) DO COME FROM ".2~.2"~#1 WHILE :1 <-
      "'?.1$.2'~'"':1/.1$.2'~#0"$#65535'"$
      "'"'&.1$.2'~'#0$#65535'"$#0'~#32767$#1"

(OK, maybe that’s an unnecessarily complicated example, and maybe it shouldn’t have included the / operator which is part of another INTERCAL extension (see Operand Overloading). Still, I thought that maybe you’d want to see how addition can be implemented in INTERCAL.)

A WHILE command starts two threads (the original thread that ran that command and a new one), one of which runs the command to the left of the WHILE and one of which runs the command to the right. Any line number applies to the left-hand command, not the WHILE as a whole, which is a metalanguage construct. NEXTING FROM, ABSTAINING FROM or similar behaviour with respect to the WHILE itself is impossible, although it’s certainly possible to abstain from either of its operands (and abstaining from the left operand has much the same effect as abstaining from the WHILE itself; the right-hand thread deliberately takes a bit of time to get started just so that this behaviour happens). The right-command thread starts just before the left command is run (so NEXTING, etc., directly to the left command will not start that loop in the first place); if that command finishes (which may be almost immediately for something like a calculate command, or take a long time for something like NEXT), that thread loops and reruns that command as long as the left command has not finished; COMING FROM that command, or a NEXT/NEXT FROM from/aiming at that command, doesn’t count as finishing that command until it is RESUMEd back to (if possible; if it’s come from, that command can never end and the right-hand loop will continue forever, or until it GIVEs UP or the loop ends due to the command ending later in another thread). A WHILE command itself exists across all threads of a multithreaded program in a way; for each left-hand command that ends (in any thread), the next time a right-hand command of the same WHILE ends it will cause the thread it’s looping in to end, regardless of whether that thread corresponds to the thread in which the left-hand command ended. (As well as a right-hand command ending, there’s also the possibility that it never got started; there is a delay before the right-hand command runs during which a left-hand command ending can prevent the right-hand thread starting in the first place; this counts as the same sort of event as terminating a right-hand loop, and can substitute for it anywhere a right-hand command ending is mentioned.) There is one exception, in that if two or more left-hand commands end in a space of time in which no right-hand commands for that WHILE ends, they together only cause one right-hand command to end. (What, did you expect the logical and orthogonal behaviour?)

The two threads produced by a WHILE (the original thread and a new copy of it) have more in common than ordinary INTERCAL threads created by COME FROM; ordinary threads share only ABSTAIN/REINSTATE information, whereas the WHILE-produced threads count as ‘woven’ threads which also share variables and stashes. (They still have separate instruction pointers, separate instruction pointer stacks, such as the NEXT stack, and separate choicepoint lists. Overloading information is shared, though.) Being woven is a relationship between two or more threads, rather than an attribute of a thread, although a thread can be referred to as being unwoven if it is not woven to any other thread.

Ordinary multithreading cannot create woven threads. When threads are created by multiple COME FROMs from an original thread, which was woven with at least one other thread, one of the resulting threads counts as the ‘original’ thread and remains woven; the rest are ‘new’ threads which initially start out with the same data as the original, but are not woven with anything. Backtracking in a thread (see Backtracking) causes it to unweave with any threads it may be woven with at the time (so the data in the thread that backtracks is set back to the data it, and the threads it was woven with at the time, had at the time of the MAYBE, but the other threads continue with the same data as before). The only way to cause three or more threads to become woven is with a new WHILE inside one of the threads that is already woven, which causes all the new threads to be woven together (the weaving relationship is transitive).


Next: , Previous: , Up: Multithreading and Backtracking   [Index]