Hi,
In the documentation for rt_mutex_acquire, it says that it should return
-ETIMEDOUT "if the mutex cannot be made available to the calling task
within the specified amount of time."
I'm not sure if this is really a bug, but I've run into a case where the
it returns the -ETIMEDOUT well before the specified amount of time has
passed. It took me a little while to track down what's happening, and
in the process I've created a small test program. Basically what's
happening in the test is that a higher priority task is holding the
mutex, releases it, and (without blocking) re-acquires the mutex. Then
the higher priority task sleeps, and the lower priority task (which
should be blocked waiting for quite some time yet) wakes up with -ETIMEDOUT.
Can anyone say whether this behavior is correct?
Thanks,
Josh
Running xenomai 2.4.4 on i686, with kernel 2.6.20.21. Output from test
program is:
at 561946, waiter_task attempting to get mutex
at 100675462, waiter_task: Error -110 from rt_mutex_acquire, with
maxWait=2000000000
at 3008820189, mutex_test is done.
----
#include <stdio.h>
#include <sys/mman.h>
#include <native/task.h>
#include <native/mutex.h>
#include <native/timer.h>
RT_TASK task, waiter;
RTIME start;
RT_MUTEX mutex;
void waiter_task( void *cookie ) {
RTIME maxWait = 2 * 1000 * 1000 * 1000LL;
printf("at %lld, waiter_task attempting to get mutex\n",
rt_timer_read()-start);
int ret = rt_mutex_acquire( &mutex, maxWait );
if ( ret == 0 )
printf("at %lld, waiter_task got mutex\n", rt_timer_read()-start);
else {
printf( "at %lld, waiter_task: Error %d from rt_mutex_acquire,
with maxWait=%lld\n",
rt_timer_read()-start, ret, maxWait );
}
}
int main( int argc, char *argv[] ) {
mlockall(MCL_CURRENT|MCL_FUTURE);
int err = rt_task_shadow( &task, "mutex_test", 15, 0 );
if ( err != 0 ) {
printf( "Error %d calling rt_task_shadow()\n", err );
return 1;
}
start = rt_timer_read();
int ret = rt_mutex_create( &mutex, 0 );
if (ret != 0) {
printf( "Error %d from rt_create_mutex\n", ret );
return 1;
}
ret = rt_mutex_acquire( &mutex, TM_INFINITE );
if (ret != 0) {
printf( "Error %d from rt_mutex_acquire\n", ret );
return 1;
}
ret = rt_task_spawn( &waiter, "mutex_waiter", 0, 2, 0, waiter_task, 0 );
if (ret != 0) {
printf( "Error %d from rt_task_spawn\n", ret );
return 1;
}
for ( int i = 0; i < 300; i++ ) {
ret = rt_task_sleep( 10 * 1000 * 1000LL );
if (ret != 0) {
printf( "at %lld, Error %d from rt_task_sleep\n",
rt_timer_read()-start, ret );
return 1;
}
if ( (i % 10) == 9 ) {
ret = rt_mutex_release( &mutex );
if ( ret != 0 )
printf( "at %lld: Error %d from rt_mutex_release, i =
%d\n", rt_timer_read()-start, ret, i );
rt_timer_spin( 100 * 1000LL );
ret = rt_mutex_acquire( &mutex, TM_INFINITE );
if ( ret != 0 )
printf( "at %lld: Error %d from rt_mutex_acquire, i =
%d\n", rt_timer_read()-start, ret, i );
}
}
printf( "at %lld, mutex_test is done.\n", rt_timer_read()-start );
return 0;
}
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help