Hello all,
I am working with Xenomai 2.4.9.1 on Kernel 2.6.30. I try to test the
pperiodic example and I always get the error code 3 in
pthread_make_periodic_np function: ESRCH -> invalid thread.
Why I get that code?
Thanks a lot,
--
Rubén González del Pozo
University of Salamanca
[email protected]
#include <stdio.h>
#include <posix/pthread.h>
#include <posix/errno.h>
#include <signal.h>
#include <sys/mman.h>
#include <rtdk.h>
static int count;
static int goon = 1;
static pthread_t id_low;
static pthread_t id_high;
#define LOW_PRIO 5
#define HIGH_PRIO 10
#undef WITH_PRINTF
#undef WITH_SIGXCPU
void init_task(int prio);
void* low_prio_task(void* dummy)
{
struct sched_param param;
int policy;
pthread_getschedparam(pthread_self(), &policy, ¶m);
rt_printf("%s: policy=%d prio=%d\n",
__FUNCTION__, policy, param.sched_priority);
param.sched_priority = LOW_PRIO;
pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
while(goon)
{
#ifdef WITH_PRINTF
pthread_set_mode_np(0, PTHREAD_PRIMARY);
rt_printf("%s %d\n", __FUNCTION__, count);
#endif
count++;
}
rt_printf("Exiting %s, count=%d\n", __FUNCTION__, count);
return 0;
}
void* high_prio_task(void* dummy)
{
struct timespec tstart = { .tv_sec = 0, .tv_nsec = 0};
#ifdef WITH_PRINTF
struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 10000000 };
#else
struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 1000000 };
#endif
unsigned long overruns = 0;
int tick = 0, step = 0, loop = 0, err;
struct sched_param param = { .sched_priority = HIGH_PRIO };
rt_printf("Starting %s\n", __FUNCTION__);
pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
#ifdef WITH_SIGXCPU
pthread_set_mode_np(0, PTHREAD_WARNSW);
#endif
rt_printf("BEFORE MAKE PERIODIC\n");
err = pthread_make_periodic_np(pthread_self(), &tstart, &tperiod);
switch(err)
{
case ESRCH:
rt_printf("ERROR make periodic: ESRCH\n");
break;
case ETIMEDOUT:
rt_printf("ERROR make periodic: ETIMEDOUT\n");
break;
default:
rt_printf("ERROR make periodic: another error: %d\n", err);
break;
}
if (err)
return (void *)err;
while (1)
{
err = pthread_wait_np(&overruns);
#if 0
if (err)
{
pthread_kill(id_low, SIGSTOP);
rt_printf("%s overruns=%lu, tick=%d, count=%d, err=%d\n",
__FUNCTION__, overruns, tick, count, err);
return 0;
}
#endif
if(step == 0 && loop > 100)
{
loop = 0;
step = 1;
init_task(LOW_PRIO);
}
else if(step == 1 && loop > 500)
{
loop = 0;
step = 2;
//goon = 0;
pthread_kill(id_low, SIGUSR1);
rt_printf("SIGUSER1 to id_low: count=%d, overruns=%lu\n",
count, overruns);
}
else if(step == 2 && loop > 500)
{
loop = 0;
step = 1;
pthread_kill(id_low, SIGUSR2);
rt_printf("SIGUSER2 to id_low: count=%d, overruns=%lu\n",
count, overruns);
}
tick++;
loop++;
}
rt_printf("Exiting %s\n", __FUNCTION__);
return 0;
}
void init_task(int prio)
{
struct sched_param parm;
pthread_attr_t attr;
pthread_attr_init(&attr);
if(prio == HIGH_PRIO)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
else
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
parm.sched_priority = prio;
pthread_attr_setschedparam(&attr, &parm);
if (prio == HIGH_PRIO)
{
pthread_create(&id_high, &attr, high_prio_task, NULL);
pthread_set_name_np(id_high,"high_prio");
}
else
{
pthread_create(&id_low, &attr, low_prio_task, NULL);
pthread_set_name_np(id_low,"low_prio");
}
}
void catch_signal(int sig)
{
rt_printf("Signal %d catched\n", sig);
}
#ifdef WITH_SIGXCPU
void catch_switch(int sig)
{
void *bt[32];
int nentries;
rt_printf("Signal %d catched\n", sig);
/* Dump a backtrace of the frame which caused the switch to
secondary mode: */
nentries = backtrace(bt,sizeof(bt) / sizeof(bt[0]));
backtrace_symbols_fd(bt,nentries,fileno(stdout));
}
#endif
static void suspend_signal_handler(int sig)
{
sigset_t signal_set;
rt_printf("suspend signal handler\n");
sigfillset(&signal_set);
sigdelset(&signal_set, SIGUSR2);
sigsuspend(&signal_set);
return;
}
static void resume_signal_handler(int sig)
{
rt_printf("resume signal handler\n");
return;
}
void init_signals(sigset_t *mask)
{
struct sigaction sigusr1, sigusr2;
sigemptyset(mask);
sigaddset(mask, SIGINT);
sigaddset(mask, SIGTERM);
sigaddset(mask, SIGHUP);
sigaddset(mask, SIGALRM);
pthread_sigmask(SIG_BLOCK, mask, NULL);
/*
* Install the signal handlers for suspend/resume.
*/
sigemptyset (&sigusr1.sa_mask);
sigusr1.sa_flags = 0;
sigusr1.sa_handler = suspend_signal_handler;
sigaction(SIGUSR1, &sigusr1, NULL);
sigemptyset (&sigusr2.sa_mask);
sigusr2.sa_flags = 0;
sigusr2.sa_handler = resume_signal_handler;
sigaction(SIGUSR2, &sigusr2, NULL);
}
int main(int argc, char *argv[])
{
sigset_t mask;
int sig;
mlockall(MCL_CURRENT|MCL_FUTURE);
rt_print_auto_init(1);
#ifdef WITH_SIGXCPU
signal(SIGXCPU, catch_switch);
#endif
#if 0
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
signal(SIGHUP, catch_signal);
#else
init_signals(&mask);
#endif
init_task(HIGH_PRIO);
#if 0
pthread_join(id_high, NULL);
#else
sigwait(&mask, &sig);
#endif
rt_printf("Exiting %s\n", __FUNCTION__);
return 0;
}_______________________________________________
Xenomai-core mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-core