Idle time in RTOS - rtos

Since idle tasks are generally used to safely consume CPU time that is not required by other software, what would happen if there was no idle task? Would the RTOS just automatically create one? Also, what other purpose do idle tasks serve other than consuming time?

what would happen if there was no idle task? Would the RTOS just automatically create one?
I doubt there is any RTOS that would do that. If there would be no idle task, then the list of runnable tasks would be empty and the scheduler would probably crash. Generally the single most important reason for idle thread's existence is to make the list of runnable tasks "never empty". This simplifies the code of scheduler.
Also, what other purpose do idle tasks serve other than consuming time?
In some systems idle task can perform some low priority activities (for example some garbage collection). It can also switch the core to low-power mode, especially on embedded devices. In that case when the idle task is run it means that there is nothing more to do, so the core can be stopped and wait for the next event (hardware interrupt or timeout) without using too much power. When the next event arrives the core is awakened by hardware and the event is processed. Either some "normal" thread will start running, or - if there is still nothing more to do - idle thread will resume and again switch to low-power mode.

If the CPU clock is running, instructions must be executed; if there were no idle task, then your OS is broken. The idle loop is an intrinsic part of the RTOS, not a user task, so the RTOS does not need to "create one automatically".
A low priority user task that never yields will prevent the idle loop from running; which is not necessarily a good thing. Such a task is not the same thing as the idle loop. For one thing any CPU usage tools the RTOS supports would report 100% usage all the time if such a task eusted - execution of the idle loop is not included is CPU usage because the CPU is always ready to respond to any interrupt event when idle - the loop does not ever cause any ready task to be delayed.
The idle task, or "idle loop" is typically just that, and empty loop that the program counter is set to when there is nothing else to do. In some architectures the loop may include a "wait-for-interrupt" instruction that stops core execution (stops clocking the core) to reduce power consumption. Since any context switch necessarily requires an interrupt to occur, the processor can if WFI is supported just stop in this loop.
Some RTOS support user hooks for the idle loop; low-priority run-to-completion functions that can operate in the background in the idle loop context.

what other purpose do idle tasks serve other than consuming time?
Most commonly, it does two things:
1. Garbage(resource) collection or cleaning
2. Initiate steps to reduce power consumption

Related

How Round robin CPU scheduling algorithm deal with I/O-bound processes?

I am recently taking a course called The principle of operating system, and I learned CPU scheduling. I am confused about Round robin scheduling, for I/O-bound process, for example, the process will use CPU for 2ms and does I/O for 8ms. Will scheduler still assign a quantum to this process when it is doing I/O? Also, when this process is doing I/O, will the scheduler wait for the I/O to complete even when the quantum expires or it will just start to execute next process? Any help would be appreciated!
Will scheduler still assign a quantum to this process when it is doing I/O?
Typically each task has a state, maybe one of:
running, currently using CPU
ready to run, waiting to use CPU
blocked, waiting for something (disk IO, a mutex, a time delay, a network packet to arrive, ...)
The scheduler only cares about tasks that are running and ready to run - e.g. it might have a (circular singly linked?) list of tasks that want CPU time, and when a task blocks the task is removed from that list (and then later when whatever the task was waiting for happens and the task is unblocked, the task is put back on the list).
Traditionally; when a task is put back on the list it's put back on the end of the list, so that a task can't repeatedly block briefly to get a new time slice and hog the CPU.
This means that if there are 2 tasks and one blocks, a round robin scheduler might do "task A, task B, task A, task B" while task A is running/ready to run; then switch to "task B, task B, task B, task B" while task A is blocked; then after task A unblocks it'd go back to "task B, task A, task B, task A, ..." (starting with task B because task A was put on the end of the list and not the start of the list).
The other thing is that tasks literally can't decide to do something that would cause them to block unless they're currently running; which means that whenever a task blocks it doesn't use its whole time slice. For example, if the scheduler is giving out 1 ms time slices then a task may block after using 0.3 ms of its time slice, leaving a remainder of 0.7 ms. For this reason the scheduler needs a timer with higher precision and the length of time slices will be rounded to the precision of the timer IRQ (e.g. if the scheduler is using a timer IRQ that occurs every 0.2 ms; then that remaining 0.7 ms left after one task blocks might be rounded to 0.8 ms leaving a spare 0.1 ms due to rounding, and the next task might actually get 1.1 ms of CPU time instead of 1.0 ms of CPU time because of that "rounding to the timer's precision").
Also; when all tasks are blocked the scheduler's timer can be suppressed/disabled (and the CPUs put into a power saving state) to reduce power consumption by preventing pointless timer IRQs from waking the CPU out of a power saving state; and when only one task can run the scheduler's timer can be also be suppressed/disabled (and the task given an "effectively infinite" time slice) to prevent the overhead of pointless timer IRQs from decreasing the performance of the task.
Note 1: Almost all universities ignore reality; starting with the extremely dodgy assumption that its possible to know how long a task will use CPU time and when it will block or use IO (followed by the assumption that everything happens in nicely "aligned to time slice duration" boundaries).
Note 2: Almost all universities assume that "IO" means the initiating task is blocked; either because the disk controller does the IO while the CPU does other things, or because one or more different task/s use the CPU to do the IO while the initiating task blocks (e.g. your task calls "read()", your task is blocked and a file system task is unblocked, the file system task asks the disk controller's driver to fetch some data, the file system task is blocked and the disk controller driver's task is unblocked, then ...). This isn't strictly true in all cases (but may be true in all cases for some operating systems).
In general time critical I/O will typically be handled by an interrupt handler rather than a round-robin scheduled process.
For example, say you have a UART with no hardware FIFO, a character arriving in its data-register, must be read before it is overwritten by the next received character. In this case the character might be placed in a software FIFO buffer (a pipe or queue). That buffer would need to be large enough to capture all data received while the receiving process is not running. When the receiving process is scheduled it will receive all buffered data at once.
In other cases, I/O may use DMA operations, which occur in parallel to CPU operations. There is still often an interrupt handler involved but it would be a DMA controller interrupt rather than an interrupt from the I/O device.
Non time-critical I/O may simply be polled or asserted in a round-robin process when no precise timing is required.
If an application has a great deal of time-critical I/O and also time critical data processing. Round-robin scheduling may not be appropriate. Real-time operating systems generally use priority based premptive scheduling, with round-robin for tasks if equal priority.
The concept that a process either uses the CPU or does I/O however makes no sense, a process runs on the CPU, whether it is performing I/O or data processing. In fact for memory mapped I/O the CPU makes no real distinction.

Who actually carries out the scheduling in a system

I came across that the process ready for execution in the ready queue are given the control of the CPU by the scheduler. The scheduler selects a process based on its scheduling algorithm and then gives the selected process the control of the CPU and later preempts if it is following a preemptive style. I would like to know that if the CPU's processing unit is being used by the processor then who exactly preempts and schedules the processes if the processing unit is not available.
now , i want to share you my thought about the OS,
and I'm sorry my English is not very fluent
What do you think about the OS? Do you think it's 'active'?
no, in my opinion , OS is just a pile of dead code in memory
and this dead code is constituted by interrupt handle function(We just called this dead code 'kernel source code')
ok, now, CPU is execute process A, and suddenly a 'interrupt' is occur, this 'interrupt' may occured because time clock or because a read system call, anyhow, a interrupt is occur. then CPU will jump the constitute interrupt handl function(CPU jump because CPU's constitute is designed). As said previously, this interrupt handle function is the part of OS kernel source code.
and CPU will execute this code. And what this code will do? this code will scheduleļ¼Œand CPU will execute this code.
Everything happens in the context of a process (Linux calls these lightweight processes but its the same).
Process scheduling generally occurs either as part of a system service call or as part of an interrupt.
In the case of a system service call, the process may determine it cannot execute so it invokes the scheduler to change the context to a new process.
The OS will schedule timer interrupts where it can do scheduling. Scheduling can also occur in other types of interrupts. Interrupts are handled by the current process.

About Idle tasks in operating systems

Every system has IDLE task which will be running if no other tasks are ready to run.So my question is , can IDLE task sleep?. My understanding is if idle task sleep then there is a chance of no task is available for the cpu to run. Is my understanding correct? Can anyone provide some link which elaborate about this topic?
It could busy-loop at lowest priority, or loop around code that sets a low-power mode, or a loop around a 'halt' instruction that stops the core execution completely.
Sleep() is not approriate - the CPU has to enter a mode where it is unavailable to any other thread until an interrupt, and Sleep() does not perform that function.
Whatever the hardware supports.
As long as the CPU is able to respond to interrupt requests, any of the above would be fine.

How does a scheduler regain control when wanted?

I'm reading about scheduling, but I can't figure out how a scheduler regains control after it invokes code in the user space.
E.g. the scheduler passes the control to some app in the user space which does some infinite loop and no other hardware interrupt occurs on an one core chip. All documents talk about the scheduler regaining control and preemptivly interrupting the user process, but how does that work if the control is never passed back to the OS?
Question: Does the scheduler register with some clock in the CPU to be given control again after X msecs? Or is there some other trick? If no, what is the C function called to register for regular (or one time?) control regains?
On Windows the Sleep(0) "causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run". This forces the scheduler to gain control.
On Linux the sched_yield "causes the calling thread to relinquish the CPU". This also forces the scheduler to gain control.
And the scheduler also gains control by interrupts too. When a thread has consumed its quantum of CPU usage the scheduler reschedules.
Windows CE for example allows to customize the thread quantum.
You may also read Thread Scheduling: quanta, switching and scheduling algorithms.
There is no single scheduler in Windows. Event based scheduling code is spread across the kernel. The kernels dispatcher routines are triggered by these events:
Thread ready for execution
Thread quantum expired
Thread priority change
Thread processor affinity change
Wait functions and Sleep functions
This Microsoft presentation is summarizing some of the scheduler principles.
If no other interrupt occured, a preemptive O/S wouldn't despatch, and the user application would loop for ever.
This won't happen, though. Typically, a preemptive scheduler will despatch on every system call, every interrupt, and every tick of the system clock. The system clock will always interrupt, so your infinite loop simply won't occur.
The Pick operating system (after its developer Dick Pick) used a non-preemptive scheduler. Software developed for this system was required to make a system call periodically to allow the kernel to despatch other processes. In this environment the kernel would otherwise lose control completely until the process terminated.
The argument used in its justification was that considerable time was spent saving and restoring the processor state during a despatch. Forcing the application to take responsibility for this would allow a faster despatch process.

What happens in the CPU when there is no user code to run?

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 or CLI 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.