[MSP430X port] Useless context switching when scheduler suspended

Hi all. This is the current vPortYield assembly implementation from the MSP430X port:

             * Manual context switch called by the portYIELD() macro.


                /* The sr needs saving before it is modified. */
                push.w  sr

                /* Now the SR is stacked we can disable interrupts. */

                /* Save the context of the current task. */

                /* Select the next task to run. */
                calla   #vTaskSwitchContext

                /* Restore the context of the new task. */
If the scheduler is suspended (as it is often in my tick-less implementation), this causes an useless context switch (and the corresponding overhead) from current task to itself. I would know if this is an intended behavior. If it is not the case, maybe should be better preventing vPortYield calls when the scheduler is suspended (I’d like to know also if an API function/macro there exists that gets the current scheduler status as uxSchedulerSuspended is declared static). Thank you in advance. Best regards, P.

[MSP430X port] Useless context switching when scheduler suspended

The whole purpose of suspending the scheduler is to stop a context switch to another task, so it is the intended (and only intended) behavior. Why are you suspending the scheduler if you want to context switch?

[MSP430X port] Useless context switching when scheduler suspended

The scheduler is suspended because I’m in the middle of a tick-less sleep, then an interrupt occurs which calls vPortYield after having detected that an higher priority task should run… But the question is general: vPortYield could be anyway called from an ISR when the scheduler is suspended, and this will cause saving and restoring the same context, so some CPU cycles could be saved skipping context save&restore when the scheduler is suspended.

[MSP430X port] Useless context switching when scheduler suspended

How this works is very dependent on the architecture – on a lot of architectures the obsolete save and restore is not performed. The MSP430 is (a thankfully) simple architecture but that comes at the cost of not having so many facilities available to the scheduler. A context switch request occurring (from anywhere) while the scheduler is suspended, including when in a tickless sleep, is held pending until the scheduler is resumed. That is why there is a rule that you cannot call blocking API functions when the scheduler is suspended – because the blocks imply won’t occur at the time it should. There is always an overhead when you enter an interrupt – so the question is how much more of an overhead is there by performing an ‘obsolete’ save and restore. Without the save and restore you will instead need to perform a partial save, test to see if the scheduler is suspended, then if so perform the rest of the save, on entry to every single interrupt – which would add more overhead, not remove overhead. The MSP430 actually uses a function to perform the yield, rather than performing it with the ISR entry and exit code, so the test as to whether the scheduler is suspended or not could be performed on entry to the function rather than within the function – but that would require a function call [xTaskGetSchedulerState()] with the run time and stack overhead that that incurs – all these things are trade offs as to which is better, but which is better depends on the actual circumstance (the program state at any time the context switch is requested). Regards.