[Bug 787] New: OS::Mutex trylock portability problem gnulinux/xenomai

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=787

Summary: OS::Mutex trylock portability problem gnulinux/xenomai
Product: RTT
Version: 1.10.3
Platform: i386 Compatible
OS/Version: Xenomai 2.x
Status: NEW
Severity: normal
Priority: P3
Component: Operating System Abstraction - Portability
AssignedTo: orocos-dev [..] ...
ReportedBy: nicolas [dot] mabire [..] ...
CC: orocos-dev [..] ...
Estimated Hours: 0.0

When called from the same thread Mutex::trylock has not the same behaviour with
linux and xenomai.

That code :

mutex = new OS::Mutex();
res = mutex->trylock();
log(Info) << "first mutex->trylock() returns:" << res << endlog();
res = mutex->trylock();
log(Info) << "second mutex->trylock() returns:" << res << endlog();

will produce that log
gnulinux:
0.038 [ Info ][TaskBrowser] first mutex->trylock() returns:1
0.038 [ Info ][TaskBrowser] second mutex->trylock() returns:0
xenomai:
0.037 [ Info ][TaskBrowser] first mutex->trylock() returns:1
0.037 [ Info ][TaskBrowser] second mutex->trylock() returns:1

rtos_mutex_trylock retourns :
- for linux : pthread_mutex_trylock
"The pthread_mutex_trylock() function shall return zero if a lock on the mutex
object referenced by mutex is acquired."
- for xenomai : rt_mutex_acquire with TM_NONBLOCK
"Passing TM_NONBLOCK causes the service to return immediately without waiting
if the mutex is still locked *** by another task *** ."

The pthread_mutex_trylock from the posix skin of Xenomai has the same behaviour
as linux.

[Bug 787] OS::Mutex trylock portability problem gnulinux/xenomai

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=787

Peter Soetens <peter [..] ...> changed:

What |Removed |Added
----------------------------------------------------------------------------
Target Milestone|--- |next-bugfix
Resolution| |FIXED
Status|NEW |RESOLVED

--- Comment #3 from Peter Soetens <peter [..] ...> 2010-12-21 10:48:20 ---
I have backported this to trunk/1.12 branch.

[Bug 787] OS::Mutex trylock portability problem gnulinux/xenomai

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=787

--- Comment #2 from Peter Soetens <peter [..] ...> 2010-10-12 16:40:59 ---
diff --git a/rtt/os/xenomai/fosi.h b/rtt/os/xenomai/fosi.h
index e972c03..45bec1b 100644
--- a/rtt/os/xenomai/fosi.h
+++ b/rtt/os/xenomai/fosi.h
@@ -263,6 +263,12 @@ static inline int rtos_nanosleep(const TIME_SPEC *rqtp,
TIME_SPEC *rmtp)
static inline int rtos_mutex_trylock( rt_mutex_t* m)
{
CHK_XENO_CALL();
+ struct rt_mutex_info info;
+ rt_mutex_inquire(m, &info );
+ if (info.locked)
+ return 0;
+ // from here on: we're sure our thread didn't lock it
+ // now check if any other thread locked it:
return rt_mutex_acquire(m, TM_NONBLOCK);
}

I believe the above 4 lines of code should do it. I wrote them against RTT
2.1.0, but they should be identical for 1.10+ Take care that you modify
rtos_mutex_trylock and *not* modify rtos_mutex_rec_trylock !

Peter

[Bug 787] OS::Mutex trylock portability problem gnulinux/

> Herman wrote :

> This is _not_ a bug! The _behaviour_ of mutexes and many other OS-level functionalities _can_ not be made uniform, and hence we should not try to do it!

I can agree with this, but this is a difficulty for a Orocos user because when you develop a component, you do not know at this time how its activity is going to be mapped into OS threads...

> Peter wrote

> I believe the above 4 lines of code should do it. I wrote them against RTT 2.1.0, but they should be identical for 1.10+ Take care that you modify rtos_mutex_trylock and *not* modify rtos_mutex_rec_trylock !

I agree with the patch you suggest. I should solve the problem.
Is this going to be in a future release ?
Another solution for me is to use the posix skin of xenomai, in order to have a portable code...

[Bug 787] OS::Mutex trylock portability problem gnulinux/

> Herman wrote :

> This is _not_ a bug! The _behaviour_ of mutexes and many other OS-level functionalities _can_ not be made uniform, and hence we should not try to do it!

I can agree with this, but this is a difficulty for a Orocos user because when you develop a component, you do not know at this time how its activity is going to be mapped into OS threads...

> Peter wrote

> I believe the above 4 lines of code should do it. I wrote them against RTT 2.1.0, but they should be identical for 1.10+ Take care that you modify rtos_mutex_trylock and *not* modify rtos_mutex_rec_trylock !

I agree with the patch you suggest. I should solve the problem. Is this going to be in a future release ? Another solution for me is to use the posix skin of xenomai, in order to have a portable code...

[Bug 787] OS::Mutex trylock portability problem gnulinux/

On Tue, 12 Oct 2010, nicolas [dot] mabire [..] ... wrote:

>> Herman wrote :
>
>> This is _not_ a bug! The _behaviour_ of mutexes and many other OS-level functionalities _can_ not be made uniform, and hence we should not try to do it!
>
> I can agree with this, but this is a difficulty for a Orocos user because
> when you develop a component, you do not know at this time how its
> activity is going to be mapped into OS threads...

And you shouldn't! If you make a component whose behaviour depends on that
knowledge, it's a bad component. Period. No apologies. No "yes but"... It's
bad.

You will be bitten sooner or later by those "implicit assumptions" on the
behaviour of the underlying OS features. And these are extremely difficult
logical errors to trace.

>> Peter wrote
>
>> I believe the above 4 lines of code should do it. I wrote them against RTT 2.1.0, but they should be identical for 1.10+ Take care that you modify rtos_mutex_trylock and *not* modify rtos_mutex_rec_trylock !
>
> I agree with the patch you suggest. I should solve the problem.
> Is this going to be in a future release ?
> Another solution for me is to use the posix skin of xenomai, in order to have a portable code...
>

Herman

[Bug 787] OS::Mutex trylock portability problem gnulinux/

On Tue, Oct 12, 2010 at 6:56 PM, <nicolas [dot] mabire [..] ...> wrote:
>> Herman wrote :
>
>> This is _not_ a bug! The _behaviour_ of mutexes and many other OS-level functionalities _can_ not be made uniform, and hence we should not try to do it!
>
> I can agree with this, but this is a difficulty for a Orocos user because when you develop a component, you do not know at this time how its activity is going to be mapped into OS threads...
>
>> Peter wrote
>
>> I believe the above 4 lines of code should do it. I wrote them against RTT 2.1.0, but they should be identical for 1.10+ Take care that you modify rtos_mutex_trylock and *not* modify rtos_mutex_rec_trylock !
>
> I agree with the patch you suggest. I should solve the problem.
> Is this going to be in a future release ?
> Another solution for me is to use the posix skin of xenomai, in order to have a portable code...

I will apply the patch on the 1.12 and 2.1 branches. Using the posix
skin has not been tested in combination with gnulinux. Especially, the
choice of CLOCK_... 's should be investigated and may be tricky to get
right.

Peter

[Bug 787] OS::Mutex trylock portability problem gnulinux/xenomai

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=787

--- Comment #1 from Peter Soetens <peter [..] ...> 2010-10-12 15:43:19 ---
A port to the posix skin is not on the immediate agenda. What we could do is
create a small construction in the xenomai rtos_mutex_trylock fosi function
that uses rt_mutex_inquire to detect if a mutex was locked or not. If it's
locked, we return 0 immediately. If it's not locked, we try to lock it. If the
lock succeeds, we return 1 immediately, if it fails, another thread has locked
it in the meantime and we return 0.

Probably only a few lines of code.

Peter

OS::Mutex trylock portability problem gnulinux/xenomai

> When called from the same thread Mutex::trylock has not the same behaviour
> with linux and xenomai.

This is _not_ a bug! The _behaviour_ of mutexes and many other OS-level
functionalities _can_ not be made uniform, and hence we should not try to
do it!

If you want to write portable code, you should (i) write your own portable
state machine, and (ii) be robust against such OS-level behavioural
dependencies...

Herman

>
> That code :
>
> mutex = new OS::Mutex();
> res = mutex->trylock();
> log(Info) << "first mutex->trylock() returns:" << res << endlog();
> res = mutex->trylock();
> log(Info) << "second mutex->trylock() returns:" << res << endlog();
>
> will produce that log
> gnulinux:
> 0.038 [ Info ][TaskBrowser] first mutex->trylock() returns:1
> 0.038 [ Info ][TaskBrowser] second mutex->trylock() returns:0
> xenomai:
> 0.037 [ Info ][TaskBrowser] first mutex->trylock() returns:1
> 0.037 [ Info ][TaskBrowser] second mutex->trylock() returns:1
>
> rtos_mutex_trylock retourns :
> - for linux : pthread_mutex_trylock
> "The pthread_mutex_trylock() function shall return zero if a lock on the
> mutex
> object referenced by mutex is acquired."
> - for xenomai : rt_mutex_acquire with TM_NONBLOCK
> "Passing TM_NONBLOCK causes the service to return immediately without
> waiting
> if the mutex is still locked *** by another task *** ."
>
> The pthread_mutex_trylock from the posix skin of Xenomai has the same
> behaviour as linux.