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 configMAXSYSCALLINTERRUPT_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.) Thanks, Rekha
The way critical sections are handled in the IA32flat port depends on the value of configMAXAPICALLINTERRUPTPRIORITY. If configMAXAPICALLINTERRUPTPRIORITY is set to portMAXPRIORITY (which is 15) then critical sections globally disable interrupts use a cli assembly instruction. Otherwise interrupts are just masked up to the configMAXAPICALLINTERRUPTPRIORITY 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.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.