pub fn enable_and_hlt()
Expand description
Atomically enable interrupts and put the CPU to sleep
Executes the sti; hlt
instruction sequence. Since the sti
instruction
keeps interrupts disabled until after the immediately following
instruction (called “interrupt shadow”), no interrupt can occur between the
two instructions. (One exception to this are non-maskable interrupts; this
is explained below.)
This function is useful to put the CPU to sleep without missing interrupts
that occur immediately before the hlt
instruction:
// there is a race between the check and the `hlt` instruction here:
if nothing_to_do() {
// <- race when the interrupt occurs here
x86_64::instructions::hlt(); // wait for the next interrupt
}
// avoid this race by using `enable_and_hlt`:
x86_64::instructions::interrupts::disable();
if nothing_to_do() {
// <- no interrupts can occur here (interrupts are disabled)
x86_64::instructions::interrupts::enable_and_hlt();
}
§Non-maskable Interrupts
On some processors, the interrupt shadow of sti
does not apply to
non-maskable interrupts (NMIs). This means that an NMI can occur between
the sti
and hlt
instruction, with the result that the CPU is put to
sleep even though a new interrupt occurred.
To work around this, it is recommended to check in the NMI handler if
the interrupt occurred between sti
and hlt
instructions. If this is the
case, the handler should increase the instruction pointer stored in the
interrupt stack frame so that the hlt
instruction is skipped.
See http://lkml.iu.edu/hypermail/linux/kernel/1009.2/01406.html for more information.