All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.