* [Xenomai] timer_create( ) example in Xenomai-3 @ 2015-09-07 11:53 Konstantinos Chalas 2015-09-07 12:52 ` Philippe Gerum 0 siblings, 1 reply; 5+ messages in thread From: Konstantinos Chalas @ 2015-09-07 11:53 UTC (permalink / raw) To: Xenomai Hello everyone, Does any of you have a working implementation of timer_create( ) in Xenomai-3? According to the documentation /only thread-directed notification is supported (evp->sigev_notify set to//SIGEV_THREAD_ID//). The thing is that the use of //SIG/EV_THREAD_ID is not common, therefore it is hard to find any help.../ /By the way, the example provided at the end of http://www.softprayog.in/tutorials/alarm-sleep-and-high-resolution-timers, crashes my system. I understand that it doesn't comply with Xenomai documentation, but should it crash the whole system? Thanks, Konstantinos / / ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Xenomai] timer_create( ) example in Xenomai-3 2015-09-07 11:53 [Xenomai] timer_create( ) example in Xenomai-3 Konstantinos Chalas @ 2015-09-07 12:52 ` Philippe Gerum 2015-09-09 13:29 ` Konstantinos Chalas 0 siblings, 1 reply; 5+ messages in thread From: Philippe Gerum @ 2015-09-07 12:52 UTC (permalink / raw) To: Konstantinos Chalas, Xenomai On 09/07/2015 01:53 PM, Konstantinos Chalas wrote: > Hello everyone, > > Does any of you have a working implementation of timer_create( ) in > Xenomai-3? > > According to the documentation /only thread-directed notification is > supported (evp->sigev_notify set to//SIGEV_THREAD_ID//). The thing is > that the use of //SIG/EV_THREAD_ID is not common, therefore it is hard > to find any help.../ > evp->sigev_notify_thread_id must be set with your recipient thread ID. There is nothing special otherwise. > /By the way, the example provided at the end of > http://www.softprayog.in/tutorials/alarm-sleep-and-high-resolution-timers, > crashes my system. I understand that it doesn't comply with Xenomai > documentation, but should it crash the whole system? > You've just proved Murphy's law article #27 is right, "If you perceive that there are four possible ways a procedure can go wrong, and you circumvent these, then a fifth way, unprepared for, will promptly develop". diff --git a/kernel/cobalt/posix/timer.c b/kernel/cobalt/posix/timer.c index e5551b3..8c4d2da 100644 --- a/kernel/cobalt/posix/timer.c +++ b/kernel/cobalt/posix/timer.c @@ -67,8 +67,10 @@ timer_init(struct cobalt_timer *timer, timer->clockid != CLOCK_REALTIME) return ERR_PTR(-EINVAL); - if (evp == NULL || evp->sigev_notify == SIGEV_NONE) - return owner; /* Assume SIGEV_THREAD_ID. */ + if (evp == NULL || evp->sigev_notify == SIGEV_NONE) { + target = owner; /* Assume SIGEV_THREAD_ID. */ + goto init; + } if (evp->sigev_notify != SIGEV_THREAD_ID) return ERR_PTR(-EINVAL); @@ -80,7 +82,7 @@ timer_init(struct cobalt_timer *timer, target = cobalt_thread_find_local(evp->sigev_notify_thread_id); if (target == NULL) return ERR_PTR(-EINVAL); - +init: /* * All standard clocks are based on the core clock, and we * want to deliver a signal when a timer elapses. -- Philippe. ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Xenomai] timer_create( ) example in Xenomai-3 2015-09-07 12:52 ` Philippe Gerum @ 2015-09-09 13:29 ` Konstantinos Chalas 2015-09-09 13:37 ` Gilles Chanteperdrix 2015-09-09 13:53 ` Philippe Gerum 0 siblings, 2 replies; 5+ messages in thread From: Konstantinos Chalas @ 2015-09-09 13:29 UTC (permalink / raw) To: Xenomai For future reference, this is what a working POSIX timer in Xenomai looks like: #include <string.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <time.h> #include <pthread.h> #include <sys/syscall.h> void* print_time (void*); timer_t timer1; pthread_t thread; int main (int argc, char **argv) { pthread_create(&thread, NULL, print_time, NULL); pthread_join(thread, NULL); exit (EXIT_SUCCESS); } void* print_time (void* args) { struct timespec tp; char buffer [80]; struct itimerspec new_value, old_value; struct sigaction action; struct sigevent sevent; sigset_t set; int signum = SIGALRM; sevent.sigev_notify = SIGEV_THREAD_ID; sevent.sigev_notify_thread_id = syscall(__NR_gettid); sevent.sigev_signo = signum; sigemptyset(&set); sigaddset(&set, signum); sigprocmask(SIG_BLOCK, &set, NULL); if (timer_create (CLOCK_MONOTONIC, &sevent, &timer1) == -1) perror ("timer_create"); new_value.it_interval.tv_sec = 1; new_value.it_interval.tv_nsec = 0; new_value.it_value.tv_sec = 1; new_value.it_value.tv_nsec = 0; if (timer_settime (timer1, 0, &new_value, &old_value) == -1) perror ("timer_settime"); while(1){ /* wait for signal (1 s) */ if (sigwait (&set, &signum) == -1) perror ("sigwait"); if (clock_gettime (CLOCK_MONOTONIC, &tp) == -1) perror ("clock_gettime"); sprintf (buffer, "%ld s %ld ns overrun = %d\n", tp.tv_sec, tp.tv_nsec, timer_getoverrun (timer1)); write (STDOUT_FILENO, buffer, strlen (buffer)); } } Thanks for the help! On 09/07/2015 02:52 PM, Philippe Gerum wrote: > On 09/07/2015 01:53 PM, Konstantinos Chalas wrote: >> Hello everyone, >> >> Does any of you have a working implementation of timer_create( ) in >> Xenomai-3? >> >> According to the documentation /only thread-directed notification is >> supported (evp->sigev_notify set to//SIGEV_THREAD_ID//). The thing is >> that the use of //SIG/EV_THREAD_ID is not common, therefore it is hard >> to find any help.../ >> > evp->sigev_notify_thread_id must be set with your recipient thread ID. > There is nothing special otherwise. > >> /By the way, the example provided at the end of >> http://www.softprayog.in/tutorials/alarm-sleep-and-high-resolution-timers, >> crashes my system. I understand that it doesn't comply with Xenomai >> documentation, but should it crash the whole system? >> > You've just proved Murphy's law article #27 is right, "If you perceive > that there are four possible ways a procedure can go wrong, and you > circumvent these, then a fifth way, unprepared for, will promptly develop". > > diff --git a/kernel/cobalt/posix/timer.c b/kernel/cobalt/posix/timer.c > index e5551b3..8c4d2da 100644 > --- a/kernel/cobalt/posix/timer.c > +++ b/kernel/cobalt/posix/timer.c > @@ -67,8 +67,10 @@ timer_init(struct cobalt_timer *timer, > timer->clockid != CLOCK_REALTIME) > return ERR_PTR(-EINVAL); > > - if (evp == NULL || evp->sigev_notify == SIGEV_NONE) > - return owner; /* Assume SIGEV_THREAD_ID. */ > + if (evp == NULL || evp->sigev_notify == SIGEV_NONE) { > + target = owner; /* Assume SIGEV_THREAD_ID. */ > + goto init; > + } > > if (evp->sigev_notify != SIGEV_THREAD_ID) > return ERR_PTR(-EINVAL); > @@ -80,7 +82,7 @@ timer_init(struct cobalt_timer *timer, > target = cobalt_thread_find_local(evp->sigev_notify_thread_id); > if (target == NULL) > return ERR_PTR(-EINVAL); > - > +init: > /* > * All standard clocks are based on the core clock, and we > * want to deliver a signal when a timer elapses. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Xenomai] timer_create( ) example in Xenomai-3 2015-09-09 13:29 ` Konstantinos Chalas @ 2015-09-09 13:37 ` Gilles Chanteperdrix 2015-09-09 13:53 ` Philippe Gerum 1 sibling, 0 replies; 5+ messages in thread From: Gilles Chanteperdrix @ 2015-09-09 13:37 UTC (permalink / raw) To: Konstantinos Chalas; +Cc: Xenomai On Wed, Sep 09, 2015 at 03:29:26PM +0200, Konstantinos Chalas wrote: > For future reference, this is what a working POSIX timer in Xenomai looks Unfortunately, this code is a very bad reference - you ignore some function potential errors - and even in the case you do not ignore them, you do not take apropriate action. For instance, if sigwait returns an error, this program will create instant lockup. -- Gilles. https://click-hack.org ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Xenomai] timer_create( ) example in Xenomai-3 2015-09-09 13:29 ` Konstantinos Chalas 2015-09-09 13:37 ` Gilles Chanteperdrix @ 2015-09-09 13:53 ` Philippe Gerum 1 sibling, 0 replies; 5+ messages in thread From: Philippe Gerum @ 2015-09-09 13:53 UTC (permalink / raw) To: Konstantinos Chalas, Xenomai On 09/09/2015 03:29 PM, Konstantinos Chalas wrote: > For future reference, this is what a working POSIX timer in Xenomai > looks like: > Good you got it working. A few additional hints: > void* print_time (void* args) > { > struct timespec tp; > char buffer [80]; > struct itimerspec new_value, old_value; > struct sigaction action; > struct sigevent sevent; > sigset_t set; > int signum = SIGALRM; > > sevent.sigev_notify = SIGEV_THREAD_ID; > sevent.sigev_notify_thread_id = syscall(__NR_gettid); > sevent.sigev_signo = signum; > Passing a NULL sigevent will get you the exact same behavior, i.e.: signum=SIGALRM, SIGEV_THREAD_ID to the calling thread. With the proper fix mentioned earlier, that is. > sigemptyset(&set); > sigaddset(&set, signum); > sigprocmask(SIG_BLOCK, &set, NULL); This masking is useless, and do not apply to Xenomai/cobalt signals but to regular ones. Cobalt signals are synchronous only, so you won't receive any async notification via some handler. sigwait*() is required to pull the pending signals explicitly. You can see this as all signals managed by Cobalt being implicitly blocked for any rt thread - of course, this does not apply to regular Linux signals which behave as usual. > while(1){ > /* wait for signal (1 s) */ > if (sigwait (&set, &signum) == -1) > perror ("sigwait"); sigwait() does not return -1, but a positive error number if something went wrong. > > if (clock_gettime (CLOCK_MONOTONIC, &tp) == -1) > perror ("clock_gettime"); > > sprintf (buffer, "%ld s %ld ns overrun = %d\n", tp.tv_sec, > tp.tv_nsec, timer_getoverrun (timer1)); Another way to retrieve the count of overruns for a timer without the extra call is to invoke sigwaitinfo(&set, &siginfo), fetching that value from siginfo.si_overrun. -- Philippe. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-09-09 13:53 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-09-07 11:53 [Xenomai] timer_create( ) example in Xenomai-3 Konstantinos Chalas 2015-09-07 12:52 ` Philippe Gerum 2015-09-09 13:29 ` Konstantinos Chalas 2015-09-09 13:37 ` Gilles Chanteperdrix 2015-09-09 13:53 ` Philippe Gerum
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.