What does an idle CPU process do?

The idle task is used for process accounting, and also to reduce energy consumption. In Linux, one idle task is created for every processor, and locked to that processor; whenever there’s no other process to run on that CPU, the idle task is scheduled. Time spent in the idle tasks appears as “idle” time in tools such as top. (Uptime is calculated differently.)

Unix seems to always have had an idle loop of some sort (but not necessarily an actual idle task, see Gilles’ answer), and even in V1 it used a WAIT instruction which stopped the processor until an interrupt occurred (it stood for “wait for interrupt”). Some other operating systems used busy loops, DOS, OS/2, and early versions of Windows in particular. For quite a long time now, CPUs have used this kind of “wait” instruction to reduce their energy consumption and heat production. You can see various implementations of idle tasks for example in arch/x86/kernel/process.c in the Linux kernel: the basic one just calls HLT, which stops the processor until an interrupt occurs (and enables the C1 energy-saving mode), the other implementations handle various bugs or inefficiencies (e.g. using MWAIT instead of HLT on some CPUs).

All this is completely separate from idle states in processes, when they’re waiting for an event (I/O etc.).


In the textbook design of a process scheduler, if the scheduler doesn't have any process to schedule (i.e. if all the processes are blocked, waiting for input), then the scheduler waits for a processor interrupt. The interrupt may indicate input from a peripheral (user action, network packet, completed read from a disk, etc.) or may be a timer interrupt that triggers a timer in a process.

Linux's scheduler doesn't have special code for a nothing-to-do case. Instead, it encodes the nothing-to-do case as a special process, the idle process. The idle process only gets scheduled when no other process is schedulable (it effectively has an infinitely low priority). The idle process is in fact part of the kernel: it's a kernel thread, i.e. a thread that executes code in the kernel, rather than code in a process. (More precisely, there's one such thread for each CPU.) When the idle process runs, it performs the wait-for-interrupt operation.

How wait-for-interrupt works depends on the processor's capabilities. With the most basic processor design, that's just a busy loop —

nothing:
    goto nothing

The processor keeps running a branch instruction forever, which accomplishes nothing. Most modern OSes don't do this unless they're running on a processor where there's nothing better, and most processors have something better. Rather than spend energy doing nothing except heating the room, ideally, the processor should be turned off. So the kernel runs code that instructs the processor to turn itself off, or at least to turn off most of the processor. There must be at least one small part that stays powered on, the interrupt controller. When a peripheral triggers an interrupt, the interrupt controller will send a wake-up signal to the main (part of) the processor.

In practice, modern CPUs such as Intel/AMD and ARM have many, complex power management settings. The OS can estimate how long the processor will stay in idle mode and will choose different low-power modes depending on this. The modes offer different compromises between power usage while idle, and the time it takes to enter and exit the idle mode. On some processors the OS can also lower the clock rate of the processor when it finds that processes aren't consuming much CPU time.