rekharamapai wrote on Thursday, December 13, 2018:
I was trying to understand the working of vPortYieldCall handler for yield defined in /portable/GCC/IA32_flat/portASM.S, for one of my race detection projects.
I understood from other posts that before a call to vTaskSwitchContext (made in vPortYieldCall), the interrupts below configMAX_SYSCALL_INTERRUPT_PRIORITY are masked (like in ARM, basepri register is set and so on).
I couldn’t find anything that does similar in the ports functions defined in portable/GCC/IA32_flat.
How are interrupts masked in such ports during a yield?
(In particular, I want tick interrupt to be masked before a call to vTaskSwitchContext.)
rtel wrote on Thursday, December 13, 2018:
The way critical sections are handled in the IA32_flat port depends on
the value of configMAX_API_CALL_INTERRUPT_PRIORITY. If
configMAX_API_CALL_INTERRUPT_PRIORITY is set to portMAX_PRIORITY (which
is 15) then critical sections globally disable interrupts use a cli
assembly instruction. Otherwise interrupts are just masked up to the
configMAX_API_CALL_INTERRUPT_PRIORITY value by writing whatever that
value is into the API task priority register. The reason for allowing
both methods was, as I recall, due to some timing behaviour related to
the decoubling of the APIC and the CPU on the devices in use to create
the port - if that timing caused a problem you could use the global
disable method as cli effects the CPU not the APIC. You can see this in
vPortEnterCritical() in that ports port.c file.
As I remember, interrupts are entered with interrupts disable, and the
timer’s interrupt handler does not re-enable then until after
vTaskSwitchContext has been called. You can see this in that port’s
portASM.s source file.