* [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.