Once again we need to look a little more at the multitasking environment in Linux and some of the data structures that make this possible.
In the header file include/linux.h a Linux Task can be in one of the following states:
TASK_RUNNING, it means that it is in the "Ready List"
TASK_INTERRUPTIBLE, task waiting for a signal or a resource (sleeping)
TASK_UNINTERRUPTIBLE, task waiting for a resource (sleeping), it is in same "Wait Queue"
TASK_ZOMBIE, task child without father
TASK_STOPPED, task being debugged
Each 10 milli-seconds (This may change with the HZ value) an Interrupt comes on IRQ0, which helps us in a multitasking environment.
The interrupt signal to the CPU comes from PIC (Programmable Interrupt Controller), say 8259, which is connected to PIT (Programmable Interval Timer) say 8253, with a clock of 1.19318 MHz.
So Time-slice = 1/HZ.
With each Time-slice we interrupt current process execution (without task switching), and the processor does housekeeping then the previous process continues to run.
Functions can be found under:
IRQ0x00_interrupt, SAVE_ALL [include/asm/hw_irq.h] do_IRQ, handle_IRQ_event [arch/i386/kernel/irq.c] timer_interrupt, do_timer_interrupt [arch/i386/kernel/time.c] do_timer, update_process_times [kernel/timer.c] do_softirq [kernel/soft_irq.c] RESTORE_ALL, while loop [arch/i386/kernel/entry.S] |
Linux and every other Unix variant manages multitasking by using a variable that keeps track of how much CPU time ha been used by the task.
Each time an interrupt is sent to IRQ 0 the variable decreases and when the count is 0 the task has to be switched.
Note | |
---|---|
The "need_resched" variable is set to 1, then assembler routines control "need_resched" and call the scheduler [kernel/sched.c] if needed at that time. |
The scheduler is a piece of code that designates which task is the next to run on the processor.
In classic Unix, when an IRQ comes (from a device), Unix makes "task switching" to interrogate the task that requested the device.
Linux ensures that the work that is not a high priority is postponed and the higher priority work is given the resources first. This tends to have a marked effect on performance of the system.
This is called "Bottom Half" where the IRQ handler re-schedules the lower level priority process to be run later in the scheduling time. Bottom-Half has been around since kernel 1.x but in the more recent versions of the kernel there is a task queue allocated to this job that appears to be more dynamic that the BH. (A tasklet is allocated for multiprocessors).
Task or process Switching is needed in many cases, some examples would be:
When a Time Slice ends the scheduler gives access to another process
If needing a resource, the process will have to go back into the sleep queue to wait for or to be given access to that resource, and only then would it be ready to be scheduled access to the processor again.
If we have a process waiting for information from another process in the form of piped information. That process would have to run before this process can continue, so the other process would be given a chance for the processor.