On Tue, Jun 01, 2010 at 04:32:37PM +0200, Philippe Gerum wrote:
> Not in the absence of syscall. We thought about this once already, when
> considering how a watchdog preempting a runaway task in primary mode
> could force a secondary mode switch: there is no sane and easy solution
> to this unfortunately.
This is exactly Sigmatek's problem: Our customers develop code
within our debugging/development environment. We want to catch
this situation (the developer implements a while(1)) with a
watchdog throwing SIGTRAP so that our debugger gets active
and can locate the problem according to the stack frame...
Find attached a separated test case (using SIGTERM which
should terminate the application). When pressing space
the system freezes (work_l() is in the while() loop with
pending signal and work_h() does not rt_task_suspend()
anymore (returning EINTR).
Then, we implement a workaround sending a rt-signal
when rt_task_suspend() returns EINTR. In the rt-signal
handler we explicitely migrate the task to secondary
domain, where linux signal handling is triggered...
Thanks,
Olli
--
Tschaeche IT-Services Tel.: +49/9134/9089850
Dr.-Ing. Oliver Tschäche Mobil: +49/176/20435601
Welluckenweg 4 Email: [email protected]
91077 Neunkirchen
/* compile with gcc -Wall -D_GNU_SOURCE -lpthread -o thisfile thisfile.c */
/*
* Simple test app to show pthread api mutex behaviour.
*
* This is compared against the Xenomai native api behaviour.
* See mutex_xeno_native.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h> /* Needed for mlockall() */
#include <limits.h>
#include <pthread.h>
#include "native/task.h"
#define MY_STACK_SIZE (100*1024) /* 100 kB is enough for now. */
static pthread_t ph, pl;
static RT_TASK xh, xl;
static volatile int state = 0;
void *
work_h(void *cookie)
{
if (rt_task_shadow(&xh, "high", 50, 0)) {
printf("failed to shadow high\n");
return NULL;
}
if (rt_task_set_periodic(&xh, TM_NOW, 1000000)) {
printf("failed to set high periodic\n");
return NULL;
}
while (1) {
if (rt_task_wait_period(NULL)) {
printf("wait_period failed\n");
break;
}
switch (state) {
case -1:
if (rt_task_suspend(&xl)) {
/* work around??? */
}
state = 1;
break;
case 1:
rt_task_resume(&xl);
state = -1;
break;
default:
break;
}
}
return NULL;
}
void *
work_l(void *cookie)
{
if (rt_task_shadow(&xl, "low", 25, 0)) {
printf("failed to shadow low\n");
return NULL;
}
if (rt_task_set_mode(0, T_PRIMARY, NULL)) {
printf("failed to migrate low\n");
return NULL;
}
state = -1;
while (1)
;
return NULL;
}
int main(void)
{
pthread_attr_t threadattr;
mlockall(MCL_CURRENT | MCL_FUTURE);
pthread_attr_init(&threadattr);
pthread_attr_setstacksize(&threadattr, MY_STACK_SIZE);
pthread_create(&ph, &threadattr, work_h, NULL);
printf("high prio watchdog started\n");
pthread_create(&pl, &threadattr, work_l, NULL);
printf("low prio work started\n");
printf("Press <ENTER> to send a signal\n");
getc(stdin);
pthread_kill(pl, SIGTERM);
/* you will not get here, because work_l() eats up your CPU */
printf("Press <ENTER> to finish\n");
getc(stdin);
printf("main finished\n");
return 0;
}
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help