It sounds reasonable that the os/rtos would schedule an "Idle task". In that case, wouldn't it be power consuming? (it sounds reasonable that the idle task will execute: while (true) {} )
This depends on the OS and the CPU architecture. On x86 (Intel compatible) the operating system might execute HLT instructions, making the CPU wait until something interesting happens, such as a hardware interrupt. This supposedly consumes very little power. Operating systems report the time spent doing this as "idle" and may even assign it to a fictional "idle" process.
So, when in Windows task manager you see that the System Idle Process is consuming 90% CPU what it really means is that the CPU does not have an actual a program to run 90% of the time.
Here's a good article on the subject: What does an idle CPU do?
Historically it's been a lot of different schemes, especially before reducing power consumption in idle was an issue.
Generally there is an "idle" process/task that runs at the lowest priority and hence always gets control when there's nothing else to do. Many older systems would simply have this process run a "do forever" loop with nothing of consequence in the loop body. One OS I heard of would run machine diagnostics in the idle process. A number of early PCs would run a memory refresh routine (since memory needed to be cycled regularly or it would "evaporate").
(A benefit of this scheme is that 100% minus the % CPU used by the idle process gives you the % CPU utilization -- a feature that was appreciated by OS designers.)
But the norm on most modern systems is to either run a "halt" or "wait" instruction or have a special flag in the process control block that even more directly tells the processor to simply stop running and go into power-saving mode.
There's always code to run, the idle task is the code if there's nothing else. It may execute a special CPU instruction to power down the CPU until a hardware interrupt arrives. On x86 CPUs it's hlt
(halt).
This answer is specific to Windows NT-based OS.
Idle thread functioality
Tasks may vary between architectures, but generally these are the tasks performed by idle threads:
- Enable interrupts to allow pending interrupts be delivered
- Disable interrupts (using
STI
orCLI
instructions, more on wiki) - On the
DEBUG
(or checked) builds, query if a kernel debugger is attached and allow breakpoints if been requested - Handle deferred procedure calls
- Check if there are any runnable threads ready for execution. If there is one, update the idle processor control block with a pointer to the thread
- Check the queues of other processors, if possible schedule thread awaiting execution on the idle processor
- Call a power management routine, which may halt a processor or downgrade CPU tick rate and do other similar power saving activities
Additional info
When there are no runnable threads for a logical processor, Windows executes a kernel-mode idle thread. There is only 1 Idle process that has as many idle threads as there are logical processors. So on a Quad core machine with 4 logical/physical processors, there will be 1 Idle process and 4 idle threads.
In Windows, Idle process has ID = 0, so do all the Idle threads. These objects are represented by standard EPROCESS/KPROCESS
and ETHREAD/KTHREAD
data structures. But they are not executive manager processes and threads objects. There are no user-land address space and no user-land code is executed..
Idle process is statically allocated at system boot time before the process manager and object manager are set up. Idle thread structures are allocated dynamically as logical processors are brought live.
Idle thread priority is set to 0. However, this value doesn't actually matter as this thread only gets executed when there are no other threads available to run. Idle thread priority is never compared with priority of any other threads.
Idle threads are also special cases for preemption. The idle thread main routine KiIdleLoop
(implementation from reactos) performs several tasks that are not interrupted by other threads. When there are no runnable threads available to run on a processor, that processor is marked as idle in a processor control block. Then if a runnable threads arrives to the queue scheduled for execution, that thread's address pointer is stored in the NextThread
pointer of the idle processor control block. During the run of an idle thread, this pointer address gets checked on every iteration inside a while
loop.
Source: Windows Internals. M. Russinovich. 6-th edition. Part 1, p.453 - 456.
© 2022 - 2024 — McMap. All rights reserved.