[SOLVED] Behavior of priority inheritance in more complex scenarios

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • [SOLVED] Behavior of priority inheritance in more complex scenarios

      Hi,

      does anybody know how priority inheritance in embOS (we use version 4.04) works in more complex scenarios? Example: lets say we have five tasks LOWEST/LOW/MEDIUM/HIGH/HIGHEST with lowest/low/medium/high/highest priority and lets say we have two mutexes A and B (implemented using OS_Use and OS_Unuse). Now the following happens:
      * LOWEST locks mutex A
      * MEDIUM interrupts LOWEST, locks mutex B and waits for mutex A
      * Priority inheritance kicks in and continues task LOWEST with priority of MEDIUM (so the LOW task is not activated even if it would be ready)
      * HIGHEST interrupts LOWEST before LOWEST can unlock mutex A. HIGHEST waits for mutex B.

      In general, we would now need to activate MEDIUM because it has the mutex which HIGHEST is waiting for. However, MEDIUM itself is blocked because it waits for mutex A. Is now task LOWEST activated because it has medium priority at the moment (because of the priority inheritance) or would be task LOW activated (if ready)? Or does priority inheritance kick in again, so that LOWEST task has now highest priority and wouldn't be interrupted by LOW or HIGH (kind of a transitive priority inheritance from HIGHEST via MEDIUM to LOWEST)?

      Another scenario:
      * LOWEST locks mutex A and B
      * Task MEDIUM inhterrupts LOWEST and waits for mutex B
      * LOWEST is activated and runs with prio of task MEDIUM
      * HIGHEST interrupts LOWEST and waits for mutex A
      * LOWEST is activated

      Is LOWEST now running with the prio of HIGHEST? What happens after releasing mutex A? Does task LOWEST now have its original prio again or does the mechanism start again so that LOWEST runs with MEDIUM prio (scheduler notices that MEDIUM is blocked by LOWEST and activates LOWEST with medium prio)?

      The documentation only describes the most basic scenario. Some more detailed information about the implementation / about the behavior in more complex scenarios would be quite nice :)

      Thx!
      Chris
    • Hi again,

      I might be completely wrong but after having a quick look at the code it seems that the logic of priority inheritance works like this (at least in embOS 4.0.4): if a task is waiting for some resource and if the task which blocks this resource is ready to run, then pActiveTask is set to the task which requires the resource and pCurrentTask is set to the task which blocks the resource. If the task which blocks the resource is waiting for some resource as well, priority inheritance is not done but the task with the next highest prio (beginning from pActiveTask) is activated.

      Lets say we have 10 tasks, two of them with very low prio (lets call these tasks LOWEST and LOW) and one task with very high prio (lets call this task HIGHEST) and 7 tasks with prios > LOW and < HIGHEST. We are in Idle at the moment, now the following could happen:
      * LOWEST is activated and locks mutex A.
      * LOW is activated and interrupts LOWEST. It locks mutex B and then has to wait for mutex A. As a result of the priority inheritance, pActiveTask is now LOW and pCurrentTask is LOWEST (so LOWEST is activated by the scheduler).
      * HIGHEST is activated, interrupts LOWEST, and has to wait for mutex B which is locked by LOW. As LOW is waiting for a resource by itself, it is not activated by the priority inheritance mechanism. Instead, the scheduler checks the ready state of all the tasks beginning from HIGHEST. As all the other tasks (between HIGHEST and LOW) are waiting, the scheduler sets pActiveTask to LOW and pCurrentTask to LOWEST (because of the priority inheritance mechanism).

      We are now in a situation, where LOWEST can be interrupted by all of the tasks which have a prio > LOW. As a result, the timing critical HIGHEST task might be blocked for quite some time.


      Another situation where priority inheritance might not work as expected is described in this thread:
      Priority inheritance and OS API inside protected section

      If the task which blocks a resource and which was activated via priority inheritance does some cooperative task switch (e.g. some OS_DelayUntil), this might result in setting pActiveTask to a task with even lower prio than the task which blocks the resource. If the delay time is over, the tasks which blocks the resource is reactivated with its own priority and not with the inherited priority (because pActiveTask is not set to the waiting task anymore), which can result in significant delays.


      However, without checking the code in detail its hard to say if all of this is really correct. Would be quite nice if somebody could confirm or disprove this, so that we can considers thes things in our application design. It would be also nice to know if the latest version of embOS works different. The release notes mention some changes in version 4.26 (and related bugfixes to these changes in newer versions) but it seems to be about performance only, not about changes in the logic of the mechanism itself.
    • Hello Chris,

      Until embOS V4.26 the logic is basically like you described: If a task gets activated but waits for a mutex, the owner of the mutex gets activated.
      In V4.26 the handling was improved to handle more complex situations more efficient (e.g. one task waits for more than one mutex, etc.).
      There is no known issue regarding priority inheritance/inversion in both embOS V4.04 and the most recent embOS V5.18.3.

      For more detailed information please contact us directly: segger.com/doc/UM01001_embOS.html#Support

      Best regards,
      Til
      Please read the forum rules before posting.

      Keep in mind, this is *not* a support forum.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support you can contact us via our support system: segger.com/ticket/

      Or you can contact us via e-mail.
    • Hi Til,

      thx for the quick feedback. So if the logic in V4.04 is like I described, doesn't this mean that the issues in the mentioned scenarios can actually happen as described? I wouldn't necessarily call these things a bug, its maybe more a limitation of the priority inheritance mechansim which maybe should be documented somewhere.

      Bests,
      Christian
    • Hello Christian,

      please contact us directly to discuss your scenario in more detail.
      If possible, could you please provide a simple application that shows your setup?
      That makes it easier to comment the behavior.
      Of course, you could program an issue with Mutex if not used correctly, like described in the link below in the sub-chapter "Deadlock".
      segger.com/doc/UM01001_embOS.html#id_00032f

      Best regards,
      Til
      Please read the forum rules before posting.

      Keep in mind, this is *not* a support forum.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support you can contact us via our support system: segger.com/ticket/

      Or you can contact us via e-mail.