Friday, May 24, 2019

Interrupt Mask on Task contexts

Interrupt Masking status at an Task needs to be restored across context switches regardless of whether to reschedule the task when the Interrupt is Masked.

In iTRON, chg_ims() does not allow context switching because it Changes IMASK and DDISP. So, the existing task remains with sleeping system calls returning E_CTX. So, the IMASK also maintained since the system calls just return with ret_ims() which will just restore the IMASK. So, interrupt forbidden status is maintained all through the execution and No interrupt occors.

But, in case of vdis_psw(), only the IRQ bit in the processor status word is directly changed, so no IMASK or DDISP reflects the Interrupt forbidden status. So, the dispatching happens as usual as long as the Task calls system calls. But, at the end of the day, when the execution returns to the Task, the interrupt prohibition status is restored and remains the one set by vdis_psw().

The thought of all of tasks that are dispatched will have the interrupt mask status zero is wrong.

Assume,

psw = vdis_psw();
                      → Interrupt does not occur.
slp_tsk();       → Task switching occurs. Interrupt occurs on the other tasks.
                      → Interrupt forbidden status of this task is restored.
while(1);       → No interrupt occurs here.

-------------------------------------------------------------------------------------------------------------------
The system calls which have already screened the Nested Interrupts, Dispatch Disable status, Interrupt Mask etc, calls the dispatch which does not do all these checks. These system calls are that are going to sleep which will screen all those first. System calls which surely switching will happen.

The system calls which themselves can be called anywhere but, the switching may happen inside the system calls based on the condition needs to call dispatch() in which the screening is done. The decision is done later and thus screening needs to be done inside the assembly call.
-------------------------------------------------------------------------------------------------------------------

I was thinking two types of scenarios, 1) system call with just returning by ret_ims() with same interrupt masking status restored. 2) system call with switching happened and switched to another task with interrupt enabled.

But, in both the cases the base task seems to be returned with interrupt mask status of its own through IMASK variable. Because the switching happens once the IMASK is passed to one of its local registers, thus it becomes local copy. So, there is no question of IMASK being global and rewritten by another task's system call.

PSW points to Processor status word, it does not considered as IMASK. But, the ret_interrupt directly refers to the Processor Status word, the switching at the anonymous interrupts does not happen. The switching happens if you call the system call.
-------------------------------------------------------------------------------------------------------------------