> On Thu, May 29, 2008 at 1:26 PM, Fabien MAHOT
> <[EMAIL PROTECTED]> wrote:
>> I succeed to reduce my test program.
>> Now, I ve got two xenomai threads.
>> threadDisplay (prio : 70) : locks a mutex (conflict_lock mutex) and
>> passes
>> between Xenomai and Linux domain. (call to sleep())
>> threadTimeOut (prio : 80) : Starts one timeout of 5ms and tries to lock
>> the mutex taken by threadDisplay. (Priority Inheritance)
>>
>> threadTimeOut waits the conflict_lock unlock of threadDisplay. With
>> priority inheritance, threadTimeOut gives its priority to threadDisplay.
>> But, threadTimeOut must also do the EndTimeOut() processing. When the
>> timeout end signal arrives, if threadDisplay is into Linux Domain, the
>> system crashes.
>
> Do you have the same crash if you use vanilla Linux timer services
> (__real_timer_create, __real_timer_settime, etc...).
>
> --
> Gilles
Hello,
I try with vanilla linux timer. If threadTimeOut sets up one or two
timeouts, now, it's ok. But if it sets up more than two timeouts, the
system crashes.
I ve got the same error kernel traces as Posix timer use.
(By the way, In which file vanilla timer services are written ?
__real_timer_create ... are declared in time.h in xenomai files. I look
for in linux and glibc sources but I don t find them.)
I send you a test program in which severals timeouts can be created.
##############################################################################################
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <time.h>
#include <math.h>
#include <signal.h>
#include <semaphore.h>
#include <errno.h>
// Timer
struct stTimeOut {
timer_t timer_h;
struct sigaction sa;
struct sigevent sig_spec;
struct itimerspec tmr_setting;
int number;
}timeOut0, timeOut1, timeOut2, timeOut3, timeOut4, timeOut5;
// Thread start
pthread_cond_t start_signal;
pthread_mutex_t main_start_lock;
bool bMainStart = false;
// Conflict mutex
pthread_mutex_t conflict_lock;
/************************ Check Functions ******************************/
void check(const char *file, int line, const char *service,
int status, int err)
{
if (status >= 0)
return;
fprintf(stderr, "%s:%d: %s: %s\n", file, line, service, strerror(err));
exit(EXIT_FAILURE);
}
#define check_pthread(expr) \
({ \
int _status = (expr); \
check(__FILE__, __LINE__, #expr, -_status, _status); \
})
#define check_unix(expr) \
check(__FILE__, __LINE__, #expr, (expr), errno)
/************************ Functions ******************************/
void DeleteTimer(timer_t timer)
{
if (timer!=NULL)
check_unix(__real_timer_delete(timer));
}
void EndTimeOut (int signo,siginfo_t *info,void*context)
{
}
void StartTimeOut (int nb_Sec, int nb_nSec, struct stTimeOut timeOut)
{
(timeOut.sa).sa_flags = SA_SIGINFO;
(timeOut.sa).sa_sigaction = EndTimeOut;
check_unix(sigaction(SIGRTMIN, &(timeOut.sa), NULL));
(timeOut.sig_spec).sigev_notify = SIGEV_SIGNAL;
(timeOut.sig_spec).sigev_signo = SIGRTMIN;
(timeOut.sig_spec).sigev_value.sival_ptr = NULL;
check_unix(__real_timer_create(CLOCK_REALTIME, &(timeOut.sig_spec),
&(timeOut.timer_h)));
(timeOut.tmr_setting).it_value.tv_sec = nb_Sec;
(timeOut.tmr_setting).it_value.tv_nsec = nb_nSec;
(timeOut.tmr_setting).it_interval.tv_sec = 0;
(timeOut.tmr_setting).it_interval.tv_nsec = 0;
check_unix(__real_timer_settime((timeOut.timer_h), 0,
&(timeOut.tmr_setting),NULL));
}
/************************** Threads ********************************/
void* threadTimeOut(void * arg)
{
check_pthread(pthread_mutex_lock(&main_start_lock));
while (!bMainStart)
check_pthread(pthread_cond_wait(&start_signal, &main_start_lock));
check_pthread(pthread_mutex_unlock(&main_start_lock));
printf("threadTimeOut : Start of timeouts\n");
StartTimeOut(0,500000000,timeOut0);
StartTimeOut(0,500000000,timeOut1);
StartTimeOut(0,500000000,timeOut2);
//StartTimeOut(0,500000000,timeOut3);
//StartTimeOut(0,500000000,timeOut4);
//StartTimeOut(0,500000000,timeOut5);
// threadTimeOut waits the conflict_lock unlock of threadDisplay
// With priority inheritance, threadTimeOut gives its priority to
// threadDisplay. But, threadTimeOut must also do the EndTimeOut()
// processing. When the timeout end signal arrives, the system crashes.
check_pthread(pthread_mutex_lock(&conflict_lock));
printf("threadTimeOut : Hold conflict_lock\n");
while (1)
{
sleep(10);
}
return NULL;
}
void* threadDisplay(void * arg)
{
// threadDisplay locks conflict_lock. Like this, when threadTimeOut
// wants conflict_lock, it must give its priority to threadDisplay.
check_pthread(pthread_mutex_lock(&conflict_lock));
printf("threadDisplay : Hold conflict_lock\n");
check_pthread(pthread_mutex_lock(&main_start_lock));
while (!bMainStart)
check_pthread(pthread_cond_wait(&start_signal, &main_start_lock));
check_pthread(pthread_mutex_unlock(&main_start_lock));
printf("Display thread\n");
sleep(10);
printf("End of display thread\n");
check_pthread(pthread_mutex_unlock(&conflict_lock));
while (1)
{
sleep(10);
}
return NULL;
}
/***********************************************************************/
void cleanup_upon_sig(int sig __attribute__((unused)))
{
DeleteTimer(timeOut0.timer_h);
DeleteTimer(timeOut1.timer_h);
DeleteTimer(timeOut2.timer_h);
DeleteTimer(timeOut3.timer_h);
DeleteTimer(timeOut4.timer_h);
DeleteTimer(timeOut5.timer_h);
exit(0);
}
int main(int argc, char** argv) {
pthread_attr_t attr;
pthread_mutexattr_t attr_proto;
pthread_t p1;
pthread_t p2;
struct sched_param sch;
check_unix(signal(SIGINT, cleanup_upon_sig));
check_unix(signal(SIGTERM, cleanup_upon_sig));
check_unix(mlockall(MCL_CURRENT|MCL_FUTURE));
// mutex and sem initialisation
check_pthread(pthread_cond_init(&start_signal, NULL));
check_pthread(pthread_mutex_init(&main_start_lock, NULL));
check_pthread(pthread_mutexattr_init(&attr_proto));
check_pthread(pthread_mutexattr_setprotocol(&attr_proto,PTHREAD_PRIO_INHERIT));
check_pthread(pthread_mutexattr_setpshared(&attr_proto,PTHREAD_PROCESS_SHARED));
check_pthread(pthread_mutex_init(&conflict_lock, &attr_proto));
check_pthread(pthread_attr_init(&attr));
check_pthread(pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED));
check_pthread(pthread_attr_setschedpolicy(&attr, SCHED_FIFO));
// TimeOut thread creation
sch.sched_priority = 80;
check_pthread(pthread_attr_setschedparam(&attr, &sch));
check_pthread(pthread_create(&p1, &attr, threadTimeOut, NULL));
// Display thread creation
sch.sched_priority = 70;
check_pthread(pthread_attr_setschedparam(&attr, &sch));
check_pthread(pthread_create(&p2, &attr, threadDisplay, NULL));
check_pthread(pthread_attr_destroy(&attr));
printf("Main condition broadcast\n");
// Start of all threads
check_pthread(pthread_mutex_lock(&main_start_lock));
bMainStart = true;
check_pthread(pthread_cond_broadcast(&start_signal));
check_pthread(pthread_mutex_unlock(&main_start_lock));
while (1)
{
sleep(5);
}
return 0;
}
##############################################################################################
Error kernel traces :
Xenomai: fatal: removing non-linked element, holder=c7741484,
qslot=c04fbfc0 at include/xenomai/nucleus/queue.h:728
CPU PID PRI TIMEOUT STAT NAME
> 0 0 -1 0 00500080 ROOT
0 2948 0 0 00300380 testTimer13
0 2950 80 0 00300180 testTimer13
0 2951 70 0 00300380 testTimer13
Master time base: clock=203530244921
c043dd40 00000000 00000000 c7741484 000000b1 c01037d1 c03bcfed c04fbfc0
c04fbfc0 c013f6e1 c03b8f16 c773c000 c04fbfc0 c03b9014 000002d8 00000086
c7741220 ffffffff 00000002 00000001 c7740820 c04f5884 c0135c49 00000000
Call Trace:
[<c01037d1>] show_stack+0x27/0x2b
[<c013f6e1>] rpi_update+0x166/0x22e
[<c0135c49>] xnpod_resume_thread+0x119/0x527
[<c0136160>] xnpod_unblock_thread+0x48/0x79
[<c01401af>] sigwake_event+0xa1/0x104
[<c012f475>] __ipipe_dispatch_event+0xb1/0x174
[<c014010e>] sigwake_event+0x0/0x104
[<c0118981>] signal_wake_up+0x3f/0x53
[<c011a91e>] send_group_sigqueue+0xcc/0x11b
[<c011f617>] posix_timer_fn+0x52/0xcb
[<c011f5c5>] posix_timer_fn+0x0/0xcb
[<c0122856>] hrtimer_run_queues+0x104/0x172
[<c0117676>] run_timer_softirq+0x12/0x18f
[<c0125e34>] tick_handle_periodic+0xf/0x5f
[<c0114a4e>] __do_softirq+0x39/0x80
[<c0114ac9>] do_softirq+0x34/0x4a
[<c0114bfa>] irq_exit+0x25/0x30
[<c01040b7>] do_IRQ+0x51/0x63
[<c012eb5d>] __ipipe_sync_stage+0xb4/0xf1
[<c0104066>] do_IRQ+0x0/0x63
[<c012eb95>] __ipipe_sync_stage+0xec/0xf1
[<c0104066>] do_IRQ+0x0/0x63
[<c012eb9a>] __xirq_end+0x0/0x37
[<c012ecd3>] ipipe_suspend_domain+0x5b/0x78
[<c012ed3f>] __ipipe_walk_pipeline+0x4f/0x8d
[<c01087ef>] __ipipe_handle_irq+0x11c/0x13c
[<c010125b>] default_idle+0x27/0x39
[<c0101234>] default_idle+0x0/0x39
[<c0102841>] common_interrupt+0x21/0x40
[<c0101234>] default_idle+0x0/0x39
[<c010125b>] default_idle+0x27/0x39
[<c0100b7c>] cpu_idle+0x42/0x6b
[<c043e9dc>] start_kernel+0x23b/0x240
[<c043e323>] unknown_bootoption+0x0/0x195
=======================
##############################################################################################
Result on the console :
threadDisplay : Hold conflict_lock
Main condition broadcast
Start of timeouts
Display thread
<----- the system is crashed
##############################################################################################
thanks
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help