Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Context switch and mutual exclusion. I assume that by context switching you mean task switching. I must note that if be honest task switching not necessary need locking. The schedulling itself in almost any case require mutual exclusion on access of some data needed to make scheduling decision, but not context switch per se, that is follow the making scheduling decision.</p> <p>Almost all modern operation system followed by design, where each thread in the system keep two stacks, one on the user mode side and another one in the kernel mode side. All that you need to make task switch is a three step action:</p> <ol> <li>Save the state of the CPU (all registers) on the stack of the task that leave CPU.</li> <li>Switch active stacks <ol> <li>Save actual stack pointer in the current task descriptor (task that leaves CPU)</li> <li>Switch pointers to the current task descriptor</li> <li>Install new stack pointer into the stack pointer register from the current task descriptor (task that arrives to the CPU)</li> </ol></li> <li>Restore state of the CPU from the stack (stack of the task that arrived to the CPU).</li> </ol> <p>As you can see, by nature context switch operates with two set of data that are local to the task, but not global. Content of the CPU registers are not an example of shared data. Note! That if there is only one code in the kernel implement context switching all context switches will goes through the same code. And in itsturn this provide guaranty that if task was switched out, the top of kernel stack of that task will contain all CPU state in the well defined format. And every time when the task will be switched in, it will be able to found CPU state data on the top of its kernel stack!</p> <p>There are two notes exist:</p> <ol> <li>Remember, that almost all instructions on the CPU executes as atomic, if they not share data with another processors. That is mean that instruction execution can't be interrupted in the middle. Due to this, switch pointers to the current task descriptor can be safely made by xchg instruction with register-based operands.</li> <li>Task switch can be interrupted by interruptions comming from the hardware. But interrupt handlers are task context independent. Due to this they will preempt task switching safely in regard to the tasks and in regard to itself through the CPU use usually use stack machine design approach.</li> </ol> <p>Mutal exclusion in the kernel. Generally speaking, kenel can be devided into two parts: hardware-driven and software-driven. The fisrt one includes code that can be invoked by the interrupts triged by hardware devices (interrupt handlers) and that isn't rely to the currently executing thread and doesn't rely to ar somehow affect context of the curently executing task, and the second one include code that is explicitly or implicitly invokes by currently executing thread (system calls and exception handlers) and usually require access to the task descriptor datas. </p> <p>This two kernel parts provides different requirenments for the data locking. The data that is used only by software-driven part of the kernel can use well known synchronization primitivs provided by the kernel environment. I mean the primitives that follow the check-and-wait approach. For example mutexes. If required data is locked task can register self in the wait queue and release CPU for another task.</p> <p>The data that can be used only by hardware-driven part (only by one particular interrupt handler) can rely to the fact that next interrupt can't be delivered to the CPU if interrupt of the same time is on handling up to the momentwhen handler will notify interrupt controller that it complete interrupt handling (so called EOI (End Of Interrupt) notification). Due to this the data used only by one interrupt handler and that using located between interrupt handler execution start and sending of EOI notification protected in thenatural way and didn't require any additional locking.</p> <p>And finally, data that is shared between software- and hardware-driven kernel parts or between different priority interrupt handlers provide most stricked requirenment to the mutal exclusion implementations. Such data can be protected neither check-wait locks nor by serial nature of same priority interrupt delivery. There are two main factors that imply to the locking requirenments for such sort of data:</p> <ol> <li>Current activity executed on the CPU can be preempted by the interrupt handler in any point of execution in arbitrary unpredictable time. So in other words hardware interrupts handling is full asynchronous process.</li> <li>Handlers can't wait resource release. Attempt to wait the resource release in interrupt handler can easily lead to the deadlock between interrupt handler waiting resource release and in the same moment blocking software-driven kernel part execution, and task owned the resours and blocked to execute as a part of software-driven kernel part to release resource.</li> </ol> <p>Due to this in such cases next synchronization technics is used:</p> <ol> <li>Use atomic operations. Note that in described context alnmost each CPU instruction can be considered as atomic. Usually by the term of atomic operation peaple means processor instruction prefixed by 'lock' prefix, but lock is needed only in the case of multiprocessor system, to prevent inconsistent physically parallel access to the same memory cell.</li> <li>Use wait-free algoritms and data structures.</li> <li>Use IST instead of ISR. This design approach assumes that the only work that must be done in the interrupt handler is schedule the Interrupt Handling Thread to run and notify it about interruption. Due to this on the one hand amount of the code running in the interrupt handler and amount of locks that it require is dramatically reduced. And on the other hand code moved from ISR to IST can use locking without any limitations.</li> <li>Most general, most common and most popular method, that attacks one of the main factor of interrupt locking requirenments - preemption. Prevention of the preemption can be done by disabling interrupts acceptance. CPU usually supports some sort of methods to disable interrupts (for example x86 processors provide two special instructions - CLI (disable interrupts) and STI (enable interrups)). If CPU doesn't provide such facilities, interrupts usually can be disabled on side of interrupt controller too (I belive that it is a case for different RISC processors). Interrupt disabling means both that no one interrupt handler will preempt execution of the protected section of code, because processor can't receive signals from the interrupt controller and that thread swithing won't be done (at least implicitly), because timer that usually trig the scheduller won't be able to deliver interrupts as all other devices. This method of synchronization is certainly necessary for kernel implementation but is too brutal. Note! It achive synchronization by disabling ALL interrupts in the system, that negatively impact interrupt handling latencies and kernel responsiveness. Due to this kernel developers tries to make such form of critical sections as rare as possible and as short as possible.</li> </ol> <p>In regard to the interrupt gate. Yes you are right. Intel processors automatically disable interrupts during entering into the interrupt gate and reenable them on iret from the handler. Due to this whole interrupt handler can be considered as executing in the atomic fashion. But! As I described on few lines above, people tries to minimize amount of code protected in such a way. As result, even if the OS kernel use interrupt gate instead of trap gate, it will try to reenable interrupts manually in the interrupt handler as quick as posible.</p> <p>NMI is a very special case. It occurance usually mean that whole world collapsed. Is anybody will care on synchronization on the moment when all system is already going down?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload