jlaitine commented on PR #16194:
URL: https://github.com/apache/nuttx/pull/16194#issuecomment-2857114818

   As this seems to be difficult subject, I'll try to explain how the priority 
boost and restore works here, and why the thread/TCB needs to keep a list of 
priority boosts. It is not really *that* complicated.
   
   A thread (T1) may hold several mutexes at (Mx) the time (it can first wait 
on M1 then on M2, then on M3). While it is holding those, other higher priority 
threads (T2, T3) may boost the priority of T1 many times by blocking on mutexes 
M2, M3), . When the T1 posts the M3, it needs to find the correct priority to 
restore to. This information is *not* necessarily in M3, the correct restore 
priority may need to be determined by M1 or M2. This logic is (correctly) 
implemented in 
https://github.com/apache/nuttx/blob/358469e5bbb5e9507777c8c0b563c761213ececd/sched/semaphore/sem_holder.c#L413
   
   So whenever a priority boost happens, the semaphore must be added to the 
current mutex holder's list in order to do proper priority restoration.
   
   Here is one step by step example to make it even more simple:
   
   Assume we have 3 threads:
   T1, base priority 1
   T2, base priority 2
   T3, base priority 3
   
   and 2 mutexes: M1 and M2. I am marking "wait on M1" as W(M1) and "post M1" 
as P(M1). When a thread 1 is running at priority x, I am marking it as T1(x), 
similarly for T2 and T3
   
   1) T1(1) is running and does W(M1) , W(M2)
   2) T2(2) gets to run, and does W(M1). It gets blocked and boosts T1 to prio 2
   3) T1(2) continues running
   4) T3(3) gets to run and does W(M2). It gets blocked and boosts T1 to prio 3
   5) T1(3) continues running and does P(M2). Priority of T1 is restored to *2* 
and not its base priority *since T1 is still holding M1, and T2 is blocked on 
that*
   6) T3(3) continues running until it is done and blocks on something else
   7) T1(2) continues running and posts M1. Priority of T1 is restored to 1
   8) T2(2) continues running
   
   Now, If you don't add the semaphore to the task's tcb->holdsem list, you go 
wrong on 5) and restore the T1 to it's base priority, causing priority 
inversion (blocking T2). Note that at 5), there is no information on M2 about 
what is the correct priority to restore to. The previous boosts *must* be 
tracked in the tcb, and this is done by adding the semaphore holder information 
to the tcb->holdsem list.
   
   I hope this clarifies the subject?
   
   Again, I am not re-writing any priority inheritance code (which is IMHO 
working correctly) in this PR. And I explained already earlier why you *always* 
need to add the holder information to the TCB:s list when the priority boost 
occurs, but how the semaphores own holder list is redundant for mutexes.
   
   Please don't mix up these two things. I am *not* tracking here if the mutex 
is being held by many threads, this is obviously not happening. But a thread 
may hold several mutexes!
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to