Home > Articles > Programming

  • Print
  • + Share This
From the author of

Coroutines

The standard way of structuring code, inherited from ALGOL, is in subroutines. Each subroutine is effectively a simple program; you run it, it does some work, and then it exits and you continue. In a simulation, lots of individual components are typically doing different things at the same time. Subroutines aren't very good at modeling this kind of behavior.

Subroutines are popular because they're easy to implement. You push the current program state onto a stack and then jump to the subroutine code. When it's done, you pop the top activation record off the stack and resume execution.

Simula didn't originate them, but it was one of the first languages to include support for coroutines, which behave like threads in a cooperative multitasking environment. They're a bit harder to implement than subroutines because they aren't hierarchical—two or more coroutines can still be in scope, and execution can pass between them.

When you write a subroutine, it has a single entry point and one or more exit points. It can call other subroutines, but execution doesn't continue in the subroutine that called it until the end. With coroutines, you have a yield statement, which pauses the current routine and allows another to continue until it yields.

Simula had detach and resume() commands. detach was a coroutine yield statement, pausing execution of the current routine and resuming execution from where the object performing the detach operation was created or last resumed. The resume statement continued execution of a detached object. This design let Simula programmers easily implement things that ran concurrently in simulation time, even though it wasn't true concurrency. In fact, true concurrency often is undesirable for simulations, because concurrency makes ensuring deterministic results much more difficult.

After Simula, coroutines fell out of favor. Io provides support for coroutines, and you can implement them in C using the ucontext interfaces, but they're not as popular as subroutines (which are a special case of coroutines) .

That's not to say that coroutines are entirely dead. The most impressive implementation I've seen in recent years is the protothreads framework for the Contiki operating system. This framework is used to implement pseudo-concurrency in an operating system that supports IPv6 and runs on 8-bit computers with 64KB of RAM.

  • + Share This
  • 🔖 Save To Your Account