Next: , Up: Multithreading and Backtracking   [Index]


10.1 Multithreading using COME FROM

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

The original multithreading implementation worked by giving a new meaning to what was previously an error condition. If in a multithreaded program (a program is marked as multithreaded using options to a compiler) two or more COME FROMs or NEXT FROMs (or a mixture of these) attempt to steal control simultaneously, the original thread splits into multiple threads, one for each of the commands trying to take control, and a different command gains control of the program in each case.

From then on, all the threads run simultaneously. The only thing shared between threads (apart from the environment in which they run) is the abstained/reinstated status of each command; everything else is separate. This means, for instance, that it’s possible to change the value of a variable in one thread, and it will not affect the corresponding variable in other threads created this way. Likewise, there is a separate NEXT stack in each thread; if both a COME FROM and a NEXT FROM aim at the same line, for instance, the NEXT FROM thread will end up with a NEXT stack entry that isn’t in the COME FROM thread, created by the NEXT FROM itself. This is known as unwoven thread creation; none of the threads created this way are ‘woven’ with any of the other threads created this way. (Whether threads are woven depends on how they were created.) If the thread being split was itself woven with other threads, exactly one of the resulting threads after the split is woven with the threads that the original thread was woven to, but the rest will not be woven to anything. (If that seems a somewhat unusual rule: well, this is INTERCAL.)

In C-INTERCAL, there are other guarantees that can be made about unwoven threads (that is, threads not woven to any other thread). In particular, they can all be guaranteed to run at approximately the same speed; to be more precise, the number of commands that have been given the chance to execute in any given thread will not differ by more than 2 from the number of commands that have been given the chance to execute in any other thread that was created at the same time. (However, COME FROMs and NEXT FROMs can make this relationship less precise; it is unspecified (in the technical sense that means the compiler can choose any option it likes and change its mind on a whim without telling anyone) whether a COME FROM or NEXT FROM aiming at the current command counts towards the command total or not, thus causing the relationship to become weaker the more of them have the chance to execute. In versions of C-INTERCAL from 0.27 onwards, there is a third guarantee; that if a COME FROM comes from itself, it will actually give other threads at least some chance to run, at some speed, by counting itself as a command every now and then; previously this requirement didn’t exist, meaning that a COME FROM could block all threads if it aimed for itself due to the speed restrictions and the fact that COME FROMs need not count towards the total command count.) Also, all commands, including any ONCE or AGAIN attached to the command, are atomic; this means that it’s impossible for another thread to conflict with what the command is doing. (In a departure from the usual INTERCAL status quo, these guarantees are somewhat better than in most other languages that implement threading, amusingly continuing to leave INTERCAL with the status of being unlike any other mainstream language.)

The only way to communicate between unwoven threads is by changing the abstention status of commands; this always affects all threads in the program, whether woven or not. (The combination of ABSTAIN and ONCE is one way to communicate atomically, due to the atomic nature of ONCE.)

If there are at least two threads, the GIVE UP command ends the current thread, rather than the current program.


Next: , Up: Multithreading and Backtracking   [Index]