xTaskResumeFromISR effect on vTaskSuspendAll

prithwee wrote on Thursday, April 16, 2009:

Hi,

What is the effect of xTaskResumeFromISR on vTaskSuspendAll in deadlock with shared object?

Below is the scenario.

Task1() // Priority == 3.
{
  while(1){
  .
  .
  .
  // some code till here…
  vTaskSuspendAll(); .
  // some critical section…
  // Some shared object like non-reentrant file system access here for both Task1 and Task2.
  // Plz note i can’t use taskENTER_CRITICAL ()/taskEXIT_CRITICAL ()
  // Referance : http://www.freertos.org/a00134.html
  xTaskResumeAll();
  .
  .
  // some code
  .
  .
  vTaskSuspend( NULL );  --> STEP-1.
  // code continues after resume from Hardware_ISR…
  .
  .
  .
  }

}
Task2() //Priority == 2.
{
  while(1){
  .
  .
  .
  // some code till here…
  vTaskSuspendAll(); --> STEP-2.
  // some critical section…
  // Some shared object like non-reentrant file system access here for both Task1 and Task2.
  // Assume that my “Hardware_ISR()” occurs here…
  // Plz note i can’t use taskENTER_CRITICAL ()/taskEXIT_CRITICAL ()
  // Referance : http://www.freertos.org/a00134.html
  xTaskResumeAll(); --> STEP-3.
  // code continues after resume…
  .
  .
  .
  }
}

Hardware_ISR()
{
  // Now i wanted to wakeup the higher priority task… i.e Task1 which is suspended @ STEP-1.   
  xTaskResumeFromISR(Task1 Handle); --> STEP-4 
}

My questions are:
1. When i call xTaskResumeFromISR(Task1 Handle)@STEP-4, will it wake up the Task1?
2. Since Task2 is lower priority than Task1,
   the Task2 is going pre-empt after task1 suspends itself @STEP-1.
   At this moment the Task2 starts in the middle of critical section.
3. Now what will happen to the Shared object like non-reentrant file system
   which is already  in access with Task2(low priority task) which is altered by Task1?
4. What is the effect of xTaskResumeAll()@STEP-3?

What are the design constartint to avoid this deadlock?

TIA.

Regrads,
Prithwee.

rtel wrote on Thursday, April 16, 2009:

> My questions are:
> 1. When i call xTaskResumeFromISR(Task1 Handle)@STEP-4, will
> it wake up the
> Task1?

Yes and no.  It will remove task 1 from the suspended list but because the scheduler is suspended it will not place it in the ready list.  Instead it will place it in the pending ready list ready for it to be placed into the ready list when the scheduler is resumed.

> 2. Since Task2 is lower priority than Task1,
>    the Task2 is going pre-empt after task1 suspends itself @STEP-1.
>    At this moment the Task2 starts in the middle of critical section.

This should not be so.  A context switch will not occur while the scheduler is suspended, so once Task2 has called vTaskSuspendAll() it will continue to be the Running state task until it calls xTaskResumeAll().  As it will never be switched out between the call to vTaskSuspendAll() and xTaskResumeAll() it will never start executing between the two calls.

Regards.

prithwee wrote on Thursday, April 16, 2009:

Dear Richard,

Thanks for the reply. I got the concept of "pending ready list".

>>This should not be so. A context switch will not occur while the scheduler is suspended, so >>once Task2 has called vTaskSuspendAll() it will continue to be the Running state task until >>it calls xTaskResumeAll(). As it will never be switched out between the call to >>vTaskSuspendAll() and xTaskResumeAll() it will never start executing between the two calls.

  What i observed is, in between vTaskSuspendAll()and xTaskResumeAll() the scheduler is suspended, but the interrupt will be live. This will cause the "Hardware_ISR()" and i want my high priority task(TASK1) to resume after ISR. At this point time, since ISR occured from the Low priority task(TASK2) will there be corruption of shared object?

i think its a case of priority inheritance. ???

Looking forward your suggestions to change my system design.

Thank you and Regards,
Prithwee.

richard_damon wrote on Thursday, April 16, 2009:

If you think of a TaskSuspendAll as a form of critical section, that no other task can interrupt, (which is what it is), then you see that you should try to minimize the period you are under this.

By definition, Task1 shouldn’t access the resource while Task2 is using it (that is why you are using some form of exclusion). If the fact that Task2 has basically exclusive use of the machine inside the region, and other tasks that don’t need this resource can’t run, even if task2 would like to block (I am not sure if it can block under a SuspendAll), then you may want to use a semaphore or a mutex to guard that resource, then other tasks not needing THAT resource, can run as needed.

If you use a mutex, then you can get Priority boosting, so when Task1 requests the resource while Task2 has it, task2 will be boosted in priority to be the same as Task1 so Task1 can get back to work quicker.

prithwee wrote on Friday, April 17, 2009:

Thanks for the suggestions.

i tried using the “xSemaphoreTake” in place of “vTaskSuspendAll” and “xSemaphoreGive” in place of “xTaskResumeAll” in the context explained in my first post.
But when the ISR occurs from the critial section of LOW PRIORITY TASK2 and xTaskResumeFromISR(HIGH PRIORITY Task1 Handle)the TASK1 is going to rusume from the suspended state and in runtime TASK1 trying to take the mutex using " xSemaphoreTake ".
Since mutex is already took by Task2 and not yet given back, TASK1 can’t take the mutex…
If i am not wrong, this is a deadlock condition.

So, i used vTaskSuspendAll/xTaskResumeAll instead of mutexsemaphore.
i have also tested with taskENTER_CRITICAL ()/taskEXIT_CRITICAL ()
and both are working fine.

During my 1st post there was some buffers memory corruption due to the malloc implementation.
Now i am using heap2 memory manager and it seems there is no memory corruption.
These buffers are basically input/ouput buffers of the FileSystem for SD-Card Read.
Since Filesystem is a Non-ReEntrant type i am trying to give a exclusion control for the 2tasks in accesing the Fiesystem.

But i am not able to find the priority inheritance property on Mutexsemaphore. What may me the reason behind this?

Correct me i am wrong.

Regards,
Prithwee

richard_damon wrote on Friday, April 17, 2009:

I don’t understand why you call Task 1 not starting up immediately a “deadlock”, Task 1 CAN’T run immediately, since the resource is busy, and if Task 1 started using it you would get corruption. Task 1 needs to wait for the resource to be available before it can use it.

A deadlock would be if Task 1 grabbed resource A, then Task 2 grabbed resource B, then tried to get A and was suspended waiting for it. If Task 1 then tries to get Resource B, it would be suspended waiting for it, and we would have a deadlock as both tasks are waiting for the other to finish and release the resource, but neither can finish until the other one does.

If you want somehow when Task1 wants the resource, that Task 2 gives it up, that is beyond what the RTOS can provide, you would need to add a message box of some sort which Task 2 check and safe points to give up the resource, and if it sees the request it stop using the resource and gives up the mutex/semaphore (letting task1 take it), task 2 can then try and take it back and resume, where it will wait for the semaphore (since Task1 has a higher priority, it will get the semaphore).

As to priority inheritance, I think it just is part of the mutex, that being a key piece of the difference between a mutex and a semaphore. Ordinary semaphores do not implement a priority inheritance, while mutexs do, thus if a high priority task blocks on a semaphore owned by a low priority task, nothing happens, while if a high priority task blocks on a mutex owned by a low priority task the low priority task temporarily inherits the high priority tasks priority until it releases the mutex.

prithwee wrote on Monday, April 20, 2009:

Thanks for the explanation. Now my code is workg fine!!!!

vTaskSuspendAll()/ xTaskResumeAll() are working fine with my context explained before.
Also changed tested with taskENTER_CRITICAL/taskEXIT_CRITICAL. Absolutly no problem at all.
taskENTER_CRITICAL/taskEXIT_CRITICAL blocks the ISR but vTaskSuspendAll()/ xTaskResumeAll() not. So, which implementation should be appropriate?

The major memory corruption happend becoz of the input/ouput buffers getting corrupted for the application decoders in the tasks. The reason behind is the memory alignment of the ip/op buffers. My DSP architecture needs a memory alignment of 8 on the buffers which uses long load/store instructions on the data memory.

The memory manager scheme is heap2. I am using all my tasks in a dynamic mode(tasks creation/deletion using CLI-command line interface).Still i feel the heap2 is not that deterministic. Is there any other open-source memory manager avilable?

Thank you and Regards,
Prithwee.