Calling a continuation is resuming a continuation. Call/CC is a system call that reifies the current computation as a continuation and passes it to a given function.speal wrote:I've been trying to follow this discussion since the idea of an alternate to processes/threads is an appealing one to me. I wasn't familiar with continuations before, but I've tried to figure it out with some reading. Maybe I've misunderstood, but it seems to me that there's nothing inherently concurrent about a continuation. My assumption was that the behavior was much like a function call, except instead of returning a single value, the continuation will yield an intermediate value, and can be resumed at a later time to return another intermediate value. Is this correct?
Like Combuster said, a continuation system includes no native support for concurrency. However, it does include native (extremely easy to implement, since bookkeeping gets delegated to user-space) support for parallelism.If I'm right, I don't see how you can construct a system of concurrency from this, as the control flow is still in one place, but is operating in a different context when resuming a continuation.
X separate processors running separate computations with a central (lock-protected or otherwise synchronized) location for storing continuations inside a "thread" abstraction with concurrency form an SMP/NUMA scheduler that runs on X processors, for any value of X. Making it run with an additional Y processors wouldn't even require recompiling the scheduler, because it can use synchronization to count the number of available processors at run-time. It would only require adding the processors to your machine and making sure that the kernel (which exports a continuation-based interface) can recognize and start those processors. The user-land scheduler will then simply count them and use them with no extra effort.
Basically, continuations are far more scalable as OS-level primitives than threads, since threads require that you recompile your kernel when you upgrade from 1 to 2 to 32 processors for best performance. A continuation-based kernel lets you either swap out a user-land scheduler on each upgrade or even just build one scheduler that detects the number of available processors and runs itself appropriately. The latter type of scheduler could trivially scale to very large numbers of processors.