This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Protecting critical sections - Disabling preemption

Hi All,

I am using SYS/BIOS 6.32 and would like to protect a data structure which is shared between different tasks. I consider Hwi_disable vs Task_disable, however what I read about them in different resources a little bit confused my mind.

From cdoc of SYS/BIOS module,  Disabling Threads section of Synchronizing DSP/BIOS Threads and http://e2e.ti.com/support/embedded/f/355/p/68413/247705.aspx#247705  post I understood that;

* Hwi_disable can prevent preemption, EXCEPT the critical section itself (the task currently running) makes a function call which cause a context switch. Otherwise a contect switch is not possible?

key = Hwi_disable();

....

Semaphore_post(...);      //This may cause a context switch, RIGHT?

Hwi_restore(key);

 

* If I want to COMPLETELY disable context switching I SHOULD use Task_disable() in order to prevent the scheduler to a change the RUNNING task?? For example in the example above If I use Task_disable before Hwi_disable() and Task_restore() after Hwi_restore, there will be no context switch until the end of Task_restore? Whenever Task_restore is called a context swtich may occur if a waiting high priority tasks exists?

 

*  Cdoc documentation states that, In the Task_disable/restore block calling Task_sleep or Task_yield can cause blocking. Is it a result of preventing the scheduler from making a context switch due to the Tak_disable() ??

 

I am not sure if I understood these rules correctly or not. I appreciate your opinions.

 

Best Regards

 

 

 

 

 

  • Hi Deniz --

    Hwi_disable/restore simply modify the register necessary to disable interrupts.  They do not update any BIOS variables to disable scheduling.   So, you should not make any scheduler calls within a Hwi_disable/restore block of code.   If you call Semaphore_post() and a higher task is made ready to run, then a task switch will occur with interrupts disabled and this is not a good thing.    If you call Semaphore_pend() and sem count is 0, a similar switch with interrupts disabled would occur.

    If you just need a critical section where only tasks share the resource and not any Hwi or Swi functions, then using Task_disable/restore() will work.   If the critical section is long with a loop or some other long operation, you might want to use a GateMutex which is a lock that can be shared by the threads trying to access that resource.   Using GateMutex will allow other threads of higher priority to run until they want to enter the same gate via GateMutex.   Task_disable/restore is much faster than GateMutex and is good for short critical sections where disabling all other Tasks is not a problem.

    A few ideas:

    (1)   Nest the calls:

    taskKey = Task_disable();
    hwiKey = Hwi_disable();

    `critical region that includes BIOS scheduler call`

    Hwi_restore(hwiKey);
    Task_restore(taskKey);

    (2)  Move the scheduler calls outside of the critical section and use Hwi_disable/restore.

    If this answered the question, please update the thread with "answered".   Or, let me know if you have further questions.

    Thanks,
    -Karl-

     

  • Thank you  Karl. You explained, but in order to be sure. Is there a possibility of a preemption without calling a Semaphore_pend/post in the critical section? For example, between a Hwi_disable/restore block even I do not call a Semaphore_pend/post  (a scheduler call), any other higher priority task can preempt the current task or not?

     

    key =  Hwi_disable()

    Do something critical; throw out the garbage! No scheduler call here (No Semaphore_post/pend and etc.).

    Hwi_restore(key)

     

    Is it possible scenario for another higher priority task to preempt our rendezvous with the garbage in the example above?

     

  • Deniz Kocak said:

    Is it possible scenario for another higher priority task to preempt our rendezvous with the garbage in the example above?

    No.  It is not possible for a preemption in this Hwi_disable/restore() section.  The only way a task switch can occur is via a system call like Semaphore_pend() or Semaphore_post() or Task_setPri(), etc.    If you don't make any such system call, then no chance for preemption.

    -Karl-