Suspended sheduler (vTaskSuspendAll), usage

anonymous wrote on Sunday, September 02, 2012:

Quote from API reference:

API functions that have the potential to cause a context switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler is suspended.

Is it strictly prohibited or just warning that most of them will cause unexpected behavior (task will block itself). I examined freertos sources and it seems to me that it is allowed, but I’m not sure… Is it allowed to perform non-blocking freertos calls (such as xSemaphoreGive()) while sheduler is suspended ?

rtel wrote on Sunday, September 02, 2012:

It is a blanket statement, made because to analyse each API function in turn and determine exactly when it is ok and when it is not, and then document that for end users, would be unworkable and confusing.  However, any call that attempts to place the calling task into the blocked state must definitely not be used.  This is because if the logic says the task should be in the Blocked state, but because the scheduler is suspended it doesn’t transition to the Blocked state, the whole application logic will be broken (if a task blocks to wait for something on a queue, but returns before either that something has arrived or a timeout has expired, then the application cannot work correctly).

Is it allowed to perform non-blocking freertos calls

In some cases, probably, given the caveat above.

such as xSemaphoreGive())

In that specific case, if giving the semaphore should cause a context switch, then you will end up with the wrong task running until such time that the scheduler is unsuspected.


anonymous wrote on Sunday, September 02, 2012:

I don’t understand clearly what you mean under “wrong tasking”. If it doesn’t break kernel logic (state machine ?) and just influences application-level logic then it’s ok. Because it is only application developer who decides whether application logic correct or not, taking into account all tasks, their states and synchronization between them. If he suspends sheduler then he must understand consequences.
To be more specific, I’m just searching alternative critical region implementation for use by user-mode tasks in FreeRTOS-MPU. Just before deciding to use global mutex it showed to me that suspending sheduler would be faster implementation (correct me if I wrong). I’m aware of that both implementations will not be protected against interrupts, it’s ok for my case.

rtel wrote on Sunday, September 02, 2012:

If you attempt to block when the scheduler is suspended, then the (implied) state machine will break, and your application cannot determine what is going on.

For example, if you call xSemaphoreTake() with a block time on a semaphore that is not available, and the scheduler is suspended, then calling task will be placed into the Blocked state (internally within the scheduler), but the task will carry on running until the scheduler is resume.  That means it will leave the xSemaphoreTake() function, and the calling task has no idea if it obtained the semaphore or not.  Worse, when the scheduler is unsuspended, the task will immediately enter the Blocked state to wait for the semaphore, but it is not even in the xSemaphoreTake() function any more - so when the semaphore is given and the task unblocked it will just carry on from where ever it happened to be when the scheduler was unsuspended and the semaphore will remain available.


anonymous wrote on Monday, September 03, 2012:

I understand it clearly. Of course, it will be stupid trying to waiting for receive something with a single task running while knowing that nobody will be able to send. (However… it makes good sense when waiting from ISR… But given your warning that it’s not intended for such usage, this case could solved by just using global variable being polled from single running task not caring about processor time.)

Anyway, I’ve just wanted to make sure. Thanks for explanation, Richard.

P.S. I just got that there are same restrictions as ones exist for critical region, even more relaxed (maybe). So suspending will be correct method for my purposes.