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;
}

Reply via email to