> On Apr 1, 2023, at 12:54 PM, David S. Alessio <david.s.ales...@gmail.com> > wrote: > > > >> On Mar 31, 2023, at 9:34 AM, Gregory Nutt <spudan...@gmail.com >> <mailto:spudan...@gmail.com>> wrote: >> >> On 3/31/2023 8:56 AM, Gregory Nutt wrote: >>> >>>> Even more. In my previous example if semaphore is posted from the interrupt >>>> we do not know which of TaskA or TaskB is no longer a "holder l" of a >>>> semaphore. >>>> >>> You are right. In this usage case, the counting semaphore is not being >>> used for locking; it is being used for signalling an event per >>> https://cwiki.apache.org/confluence/display/NUTTX/Signaling+Semaphores+and+Priority+Inheritance >>> >>> <https://cwiki.apache.org/confluence/display/NUTTX/Signaling+Semaphores+and+Priority+Inheritance> >>> >>> In that case, priority inheritance must be turned off. >>> >> You example is really confusing because you are mixing two different >> concepts, just subtly enough to be really confusing. If a counting >> semaphore is used for locking a set of multiple resources, the posting the >> semaphore does not release the resource. That is not the way that it is >> done. Here is a more believable example of how this would work: >> >> 1. TaskA with priority 10 allocates DMA0 channel by calling a DMA >> channel allocation function. If a DMA channel is available, it is >> allocated and the allocation function takes the semaphore. TaskA >> then starts DMA activity. >> 2. TaskA waits on another signaling semaphore for the DMA to complete. >> 3. TaskB with priority 20 does the same. >> 4. TaskC with priority 30 wants to allocate a DMA channel. It calls >> the channel allocation function which waits on the sempahore for a >> count to be available. This boost the priority of TaskA and TaskB >> to 30. >> 5. When the DMA started by TaskA completes, it signals TaskA which >> calls the resource deallocation function which increments the >> counting semaphore, giving the count to TaskC and storing the base >> priorities. >> >> The confusion arises because you are mixing the signaling logic with the >> resource deallocation logic. > > > Greg, quite right. But Petro himself pointed out: >> TaskC with priority 30 wants to allocate a DMA channel, so boosts priority >> of TaskA and TaskB to 30 (even if that will not lead to fasted DMA >> operation completion). > > > So what is the problem here for which Priority Inheritance is the solution? > > Technically, there is priority inversion here, but 1) it’s not unbounded, the > channel will be free as soon as DMA completes; and 2) boosting task priority > will not reduce the latency of freeing a DMA channel. > > This scenario requires a counting semaphore that’s used as for signaling HW > resource availability; and if there are any blocked callers, the highest > priority caller is unblocked first.
I should add: the DMA channel should be freed either 1) in the ISR handling DMA interrupts after cleaning up HW, or if there’s a bit more work to do in cleanup up after DMA, in a HP worker thread. In this way the handing of the DMA channel(s), counting semaphore; and their blockers is completely independent of the priority of the caller.