Articles

Previous entries

Interrupts

There were dozens of tasks made up the system, and they generally had at least one other task that they worked directly with. While we were generally pretty good about not getting our interrupts tangled up in what was an interrupt-rich environment.

Programmers often miss something that leaves one task hanging for want of an interrupt, or two instances of a task running. I remember a paper by Dijkstra saying that interrupts were to be avoided, as you would miss something that was happening that was not described by the page you were looking at. At the time in the brashness of my youth, having been dealing with interrupt-rich environments for a couple of years, I muttered "You just have to try a little harder to get it right"

This is admittedly the "You're holding it wrong" retort that isn't useful. Watching programmers struggle with Async/Await (and related paradigms) these days is painful. These are supposedly higher-level language--why should it be harder than assembly?

As an aside, Dijkstra's admonition could well apply to a lot of Object Oriented programming, as things that are important to your program get hidden, and thus are tough to reason about.

It well could be that for languages like C that are supposedly close to the machine that with respect to things like multi-tasking, too much is out of sight and thus hard to reason about. In the Sigma 5 environment, it was all right there. It was aided by our use of a fairly clean design where the paradigm of "one interrupt, one task" was used throughout.

Coroutines

The trick was to effectively begin the task in the middle. Each task would effectively be a loop. The top of the loop was the work it needed to do to pass information and interrupts to a cooperating task. Then, by use of a cleverly named macro, the task would "request" an interrupt from the operating system. In reality, this was just a waitinstruction. This relinquished the CPU to other tasks. When the interrupt assigned to this task came in, the execution would resume following the waitinstruction. The work then was likely cleanup, e.g., releasing a buffer. Then back to the top of the routine to prepare work for the cooperating task.

Mike pointed out that you could also think of this way of looking at the state of the task as being described in part by the Instruction Pointer address.

Recent entries