Dear all,
here is another small demo... this time of a periodic thread in POSIX.
It works under Xenomai, but it fails under Posix Real-Time.
The reason of the failure is the SIGUSR1 not being blocked by the main
thread. If in main() the comments below the note "// REMOVE THE COMMENTS
BELOW" are removed, then the signal is masked also in the main(), and as
a result the POSIX version works.
The question I have is if the behavior in Xenomai (that is, not failing
like the POSIX counterpart) is correct or not...
bye
Paolo
--
Evidence S.R.L. - Paolo Gai, CEO
http://www.evidence.eu.com Tel: +39 0587 274823 Fax: +39 0587 291904
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
void abort_perror(const char *msg)
{
perror(msg);
exit(1);
}
void *my_periodic_thread (void *cookie)
{
struct itimerspec its;
struct sigevent sig;
sigset_t blocked;
siginfo_t si;
timer_t mytimer;
int i;
/* create a timer that will be used to periodically send a signal */
sig.sigev_notify = SIGEV_SIGNAL;
sig.sigev_signo = SIGUSR1;
sig.sigev_value.sival_ptr = &sig;
if(timer_create(CLOCK_REALTIME, &sig, &mytimer))
abort_perror("timer_create");
/* block the signal used by the timer */
sigemptyset(&blocked);
sigaddset(&blocked, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &blocked, NULL);
/* set the periodic timer */
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 40000000; /* 40 ms */
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 20000000; /* 20 ms */;
if(timer_settime(mytimer, 0, &its, NULL))
abort_perror("timer_settime");
printf("periodic thread started...\n");
for (i=0; i<40; i++) {
while (sigwaitinfo(&blocked, &si) == -1 && errno == EINTR);
/* The thread body */
printf("%d\n",i);
}
printf("...periodic thread end!\n");
timer_delete(mytimer);
return NULL;
}
int main()
{
pthread_t mythread;
pthread_attr_t myattr;
struct sched_param myparam;
void *returnvalue;
sigset_t blocked;
/* block the signal used by the timer */
// REMOVE THE COMMENTS BELOW
// sigemptyset(&blocked);
// sigaddset(&blocked, SIGUSR1);
// pthread_sigmask(SIG_BLOCK, &blocked, NULL);
/* initializes the thread attribute */
pthread_attr_init(&myattr);
pthread_attr_setinheritsched(&myattr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&myattr, SCHED_FIFO);
myparam.sched_priority = 3;
pthread_attr_setschedparam(&myattr, &myparam);
printf("starting a periodic thread...\n");
if (pthread_create(&mythread, &myattr, my_periodic_thread, NULL))
abort_perror("pthread_create");
pthread_attr_destroy(&myattr);
/* wait the end of the thread we just created */
pthread_join(mythread, &returnvalue);
printf("ending main...\n");
return 0;
}