Re: [riot-devel] Mutex and thread priority

2018-11-28 Thread Baptiste Clenet
I've opened an Issue on github showing how to reproduce:
https://github.com/RIOT-OS/RIOT/issues/10495


Le mer. 28 nov. 2018 12:03, Baptiste Clenet  a écrit :

> The behavior is only seen when ethos is used:
> Checkout my branch:
> https://github.com/biboc/RIOT/tree/uart_mutex_thread_pb
> And run example uart-thread-mutex_pb_BR on samr21-xpro (make flash
> BOARD=samr21-xpro)
>
> See output:
> 2018-11-28 11:58:50.71 ~~33 `@0909]!UHCP@~~}!main(): This is RIOT!
> (Version: 2018.10-RC1-330-gd8cfe-uart_mutex_thread_pb)
> 2018-11-28 11:58:50.71 ~~}!RIOT border router example application
> 2018-11-28 11:58:50.72 ~~}!THREAD
>
> 2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+
> 2018-11-28 11:58:50.74 ~~}!THREAD 2-|+2-|+2-|+2-|+THREAD
>
> 1_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*1
> 2018-11-28 11:58:50.75
>
> ~~}!2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+
> 2018-11-28 11:58:50.76 ~~}!THREAD
>
> 2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+
>
> Le jeu. 22 nov. 2018 à 15:44, Baptiste Clenet  a
> écrit :
> >
> > Thanks for your answer.
> >
> > Le jeu. 22 nov. 2018 12:51, Juan Ignacio Carrano 
> a écrit :
> >>
> >> Hi Baptiste,
> >>
> >> On 11/22/18 12:11 PM, Baptiste Clenet wrote:
> >> > Hi,
> >> > I have looked at mutex.c and thread.c and I've understood that a
> >> > thread with higher priority (it has priority) will unlock the mutex
> >> > even if thread with lower priority has not finished/unlock the mutex?
> >> > Am I right?
> >>
> >> You are referring to a situation in which a thread unlocks a mutex it
> >> did not lock before?
> >
> >
> > No. A thread A (high priority) locks a mutex which is locked by thread B
> (low priority)
> > And it seems that scheduler stops thread B and make thread A run.
> >>
> >>
> >> In that case the mutex is not behaving as such, but rather as a generic
> >> lock, and any thread can unlock it. See
> >> https://github.com/RIOT-OS/RIOT/issues/9594 .
> >>
> >> If you want the mutex to actually behave as a mutex you should ensure
> >> you never have an unlock without a matching lock (i.e. that the only
> >> thread that can unlock a mutex is the one that locked it and thus own
> >> it). RIOT's mutexes do not enforce that, so you must resolve it by
> >> careful usage.
> >>
> >> > Now, in my case, I use UART with ethos (which use a mutex) and what
> >> > happens on my case is:
> >> > * I have thread A (high priority), thread B (low priority)
> >> > * B starts to write on UART an long str
> >> > * A wants to write on UART an lock the mutex (ethos) but because it
> >> > has higher priority, it sends its message over UART until end of str
> >> > * B can continue and finish to send its str
> >> >
> >>
> >> So you are saying that the lower priority "B" thread is being preempted
> >> and it's output interrupted by A's output?
> >
> >
> > Yes exactly and this my problem. In my case, main thread with shell is
> being preempted by one of network stack threads
> >
> > Let le explain again what I see:
> > Context:
> > * two threads: main thread (low prio) with shell and ipv6 thread (high
> prio)
> > Sequence:
> > 1. Main thread starts to send a long str by UART via ethos
> (ethos_send_frame)
> > 2. Main thread locks ethos mutex in ethos_send_frame
> > 3. Ipv6 thread wants to send a str by UART, so ethos_send_frame is
> called and ipv6 thread tries to locks ethos mutex.
> >
> > Result: What I see is that main thread str is cut by ipv6 thread. Str
> seen from UART reception:
> > [START_STR_MAIN_THREAD][IPV6_THREAD_STR][END_STR_MAIN_THREAD]
> >
> > 4. IMO, ipv6 thread preempts main thread and, I don't really how,
> manages to access UART device and send its str before main thread can
> finish to send its str
> >
> > Result is that main thread str is cut
> >
> > Please have a look at ethos.c and especially ethos_send_frame() function
> to better understand what I say.
> >
> >
> >
> >
> >>
> >> I'm not familiar with ethos, but my intuition is that, while it may have
> >> a mutex, it may not be programmed in a way that the UART access is
> >> exclusive too. Exclusive access to UART would not be a good idea as in
> >> cases like yours it opens the door to priority inversions.
> >>
> >> > So I'm wondering why a thread with higher priority should be able to
> >> > unlock a mutex locked by a thread with lower priorty?
> >> >
> >>
> >> Actually any thread can unlock a mutex locked by another thread. What
> >> can never happen is that a thread _locks_ a mutex locked by another
> >> thread. In your mind, replace the word "mutex" with "lock" and things
> >> may become clearer.
> >>
> >> Regards,
> >>
> >> Juan.
> >> ___
> >> devel mailing list
> >> devel@riot-os.org
> >> 

Re: [riot-devel] Mutex and thread priority

2018-11-28 Thread Baptiste Clenet
The behavior is only seen when ethos is used:
Checkout my branch: https://github.com/biboc/RIOT/tree/uart_mutex_thread_pb
And run example uart-thread-mutex_pb_BR on samr21-xpro (make flash
BOARD=samr21-xpro)

See output:
2018-11-28 11:58:50.71 ~~33 `@0909]!UHCP@~~}!main(): This is RIOT!
(Version: 2018.10-RC1-330-gd8cfe-uart_mutex_thread_pb)
2018-11-28 11:58:50.71 ~~}!RIOT border router example application
2018-11-28 11:58:50.72 ~~}!THREAD
2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+
2018-11-28 11:58:50.74 ~~}!THREAD 2-|+2-|+2-|+2-|+THREAD
1_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*11_!*1
2018-11-28 11:58:50.75
~~}!2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+
2018-11-28 11:58:50.76 ~~}!THREAD
2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+2-|+

Le jeu. 22 nov. 2018 à 15:44, Baptiste Clenet  a écrit :
>
> Thanks for your answer.
>
> Le jeu. 22 nov. 2018 12:51, Juan Ignacio Carrano  a 
> écrit :
>>
>> Hi Baptiste,
>>
>> On 11/22/18 12:11 PM, Baptiste Clenet wrote:
>> > Hi,
>> > I have looked at mutex.c and thread.c and I've understood that a
>> > thread with higher priority (it has priority) will unlock the mutex
>> > even if thread with lower priority has not finished/unlock the mutex?
>> > Am I right?
>>
>> You are referring to a situation in which a thread unlocks a mutex it
>> did not lock before?
>
>
> No. A thread A (high priority) locks a mutex which is locked by thread B (low 
> priority)
> And it seems that scheduler stops thread B and make thread A run.
>>
>>
>> In that case the mutex is not behaving as such, but rather as a generic
>> lock, and any thread can unlock it. See
>> https://github.com/RIOT-OS/RIOT/issues/9594 .
>>
>> If you want the mutex to actually behave as a mutex you should ensure
>> you never have an unlock without a matching lock (i.e. that the only
>> thread that can unlock a mutex is the one that locked it and thus own
>> it). RIOT's mutexes do not enforce that, so you must resolve it by
>> careful usage.
>>
>> > Now, in my case, I use UART with ethos (which use a mutex) and what
>> > happens on my case is:
>> > * I have thread A (high priority), thread B (low priority)
>> > * B starts to write on UART an long str
>> > * A wants to write on UART an lock the mutex (ethos) but because it
>> > has higher priority, it sends its message over UART until end of str
>> > * B can continue and finish to send its str
>> >
>>
>> So you are saying that the lower priority "B" thread is being preempted
>> and it's output interrupted by A's output?
>
>
> Yes exactly and this my problem. In my case, main thread with shell is being 
> preempted by one of network stack threads
>
> Let le explain again what I see:
> Context:
> * two threads: main thread (low prio) with shell and ipv6 thread (high prio)
> Sequence:
> 1. Main thread starts to send a long str by UART via ethos (ethos_send_frame)
> 2. Main thread locks ethos mutex in ethos_send_frame
> 3. Ipv6 thread wants to send a str by UART, so ethos_send_frame is called and 
> ipv6 thread tries to locks ethos mutex.
>
> Result: What I see is that main thread str is cut by ipv6 thread. Str seen 
> from UART reception:
> [START_STR_MAIN_THREAD][IPV6_THREAD_STR][END_STR_MAIN_THREAD]
>
> 4. IMO, ipv6 thread preempts main thread and, I don't really how, manages to 
> access UART device and send its str before main thread can finish to send its 
> str
>
> Result is that main thread str is cut
>
> Please have a look at ethos.c and especially ethos_send_frame() function to 
> better understand what I say.
>
>
>
>
>>
>> I'm not familiar with ethos, but my intuition is that, while it may have
>> a mutex, it may not be programmed in a way that the UART access is
>> exclusive too. Exclusive access to UART would not be a good idea as in
>> cases like yours it opens the door to priority inversions.
>>
>> > So I'm wondering why a thread with higher priority should be able to
>> > unlock a mutex locked by a thread with lower priorty?
>> >
>>
>> Actually any thread can unlock a mutex locked by another thread. What
>> can never happen is that a thread _locks_ a mutex locked by another
>> thread. In your mind, replace the word "mutex" with "lock" and things
>> may become clearer.
>>
>> Regards,
>>
>> Juan.
>> ___
>> devel mailing list
>> devel@riot-os.org
>> https://lists.riot-os.org/mailman/listinfo/devel



-- 
Baptiste
___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel