Interrupt handlers can encounter difficulties particularly when further interrupts occur while they are executing. Although this can be prevented by disabling interrupts during processing by a handler, this creates other problems such as missing important interrupts. Masking (the term used to denote the selective disabling of one or more interrupts) can therefore only be used for short periods.
ISRs must therefore satisfy two requirements:
1. Implementation (above all, when other interrupts are disabled) must consist of as little code as possible to support rapid processing.
2. Interrupt handler routines that can be invoked during the processing of other ISRs must not interfere with each other.
Whereas the latter requirement can be satisfied by intelligent programming and clever ISR design, it is rather more difficult to fulfill the former. Depending on the specific interrupt, a fixed program must be run to satisfy the minimum requirements for remedying the situation. Code size cannot therefore be reduced arbitrarily.
How does the kernel resolve this dilemma? Not every part of an ISR is equally important. Generally, each handler routine can be divided into three parts of differing significance:
1. Critical actions must be executed immediately following an interrupt. Otherwise, system stability or correct operation of the computer cannot be maintained. Other interrupts must be disabled when such actions are performed.
2. Noncritical actions should also be performed as quickly as possible but with enabled interrupts (they may therefore be interrupted by other system events).
3. Deferrable actions are not particularly important and need not be implemented in the interrupt handler. The kernel can delay these actions and perform them when it has nothing better to do.
The kernel makes tasklets available to perform deferrable actions at a later time. I deal with tasklets in more detail in Section 14.3.
Continue reading here: Data Structures
Was this article helpful?