Table of Contents

Interrupts at instruction boundaries

A CPU core executes one machine instruction at a time, and it accepts a pending interrupt only at the seam between two of them: the current instruction completes, the next one has not started, and the core jumps to the handler from that exact point. "An interrupt can fire between any two instructions" means precisely that: any adjacent pair in the instruction stream is a legal delivery point. One instruction is atomic with respect to interrupts; nothing longer is.

Compiled code turns one source line into many instructions, so one line contains many boundaries. Even x++ is a load, an add and a store: an interrupt can land after the load and before the store, the handler can run for a long time, wake other threads, or switch to another thread entirely, and the interrupted code then resumes with no way to tell anything happened, on state that may have changed under it. A multi-instruction sequence is only atomic against interrupts if interrupts are masked around it, or if the hardware offers the whole operation as a single atomic instruction (a CompareExchange, for example).

In the Cosmos kernel this is the constraint the scheduler is built around: every lifecycle transition runs with interrupts disabled, and the blocking primitives follow the park protocol so a wake-up delivered on one of these boundaries, mid-park, is never lost. It is also why a preempted thread is rarely stopped at a safepoint and gets the conservative scan. See Preemption.